DES加密算法文档
联邦数据加密标准(des)算法数据加密

文章标题:深入探讨联邦数据加密标准(DES)算法数据加密随着信息化时代的不断发展,数据安全问题变得愈发突出。
在处理机密信息时,保护数据的安全性至关重要。
而联邦数据加密标准(DES)算法作为一种被广泛应用的数据加密方式,其加密原理和应用领域备受关注。
本文将从深度和广度的角度,全面探讨DES算法的数据加密,让我们共同深入理解这一重要技术。
一、理解DES算法1.1 DES算法的基本概念在加密领域,DES算法是一种对称密钥加密算法,它使用相同的密钥对数据进行加密和解密。
其基本原理是通过将明文按照密钥进行置换和替换运算,生成密文,从而实现数据的加密。
1.2 DES算法的加密过程DES算法的加密过程包括初始置换、16轮迭代运算和终结置换。
在初始置换阶段,明文经过一系列置换操作后得到L0和R0,然后进行16轮迭代运算,最终得到L16和R16。
通过终结置换生成密文,完成加密过程。
1.3 DES算法的密钥管理DES算法的密钥长度为56位,但采用64位的密钥空间,在加密和解密中对密钥进行了置换和选择操作。
密钥管理是DES算法中至关重要的一环,合理的密钥管理可以有效提升数据的安全性。
二、DES算法的应用领域2.1 网络数据传输安全在网络数据传输安全领域,DES算法被广泛应用于加密通信协议、虚拟专用网络等方面,保障了网络数据的安全传输和交换。
2.2 数据存储安全在数据存储领域,DES算法可用于对存储在磁盘上的数据进行加密保护,防止未经授权的访问和篡改。
2.3 金融交易安全在金融领域,DES算法可用于加密银行卡交易数据、电子支付信息等,保障了用户资金安全和交易隐私。
三、对DES算法的个人观点和理解在我看来,DES算法作为一种经典的对称密钥加密算法,在数据安全领域的应用前景广阔。
然而,随着计算机算力的不断提升,DES算法的安全性逐渐受到挑战,其密钥长度较短、加密速度较慢等问题也亟待解决。
针对DES算法的不足之处,我们可以结合其他加密算法,如AES算法、RSA算法等,构建更为安全和高效的数据加密方案。
des算法c++实现--文档

高级编程DES加密算法C++程序实现姓名:***学号:*********专业:电路与系统一、DES算法简要介绍DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
DES工作的基本原理是,其入口参数有三个:key、data、mode。
key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。
当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。
实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。
DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。
而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,DES算法加密的明文已经被高速计算机破解,但是DES目前仍然得到广泛的应用,在某些场合仍然发挥余热。
12二、C++实现简要介绍2.1 密钥生成 2.1.1 取得密钥从用户处取得一个64位(本文如未特指,均指二进制位))长的密码key ,在程序实现中,用一9位字符数组存放用户输入的八个字符,然后将字符数组转换成二进制形式存储在一长度为64的int 型数组当中。
程序流程图如图表1示。
去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥。
des加密算法实验报告

DES加密算法实验报告1. 引言DES(Data Encryption Standard)是一种对称密码算法,于1977年被美国联邦信息处理标准(FIPS)确定为联邦标准。
DES加密算法采用分组密码的思想,将明文按照64位分为一组,经过一系列的置换、替代和迭代操作,最终输出加密后的密文。
本实验旨在通过对DES加密算法的实际操作,深入理解DES的工作原理和加密过程。
2. 实验步骤2.1. 密钥生成DES加密算法的核心在于密钥的生成。
密钥生成过程如下:1.将64位的初始密钥根据置换表进行置换,生成56位密钥。
2.将56位密钥分为两个28位的子密钥。
3.对两个子密钥进行循环左移操作,得到循环左移后的子密钥。
4.将两个循环左移后的子密钥合并,并根据压缩置换表生成48位的轮密钥。
2.2. 加密过程加密过程如下:1.将64位的明文按照初始置换表进行置换,得到置换后的明文。
2.将置换后的明文分为左右两部分L0和R0,每部分32位。
3.进行16轮迭代操作,每轮操作包括以下步骤:–将R(i-1)作为输入,经过扩展置换表扩展为48位。
–将扩展后的48位数据与轮密钥Ki进行异或操作。
–将异或结果按照S盒进行替代操作,得到替代后的32位数据。
–对替代后的32位数据进行置换,得到置换后的32位数据。
–将置换后的32位数据与L(i-1)进行异或操作,得到Ri。
–将R(i-1)赋值给L(i)。
4.将最后一轮迭代后得到的数据合并为64位数据。
5.对合并后的64位数据进行逆置换,得到加密后的64位密文。
3. 实验结果对于给定的明文和密钥,进行DES加密实验,得到加密后的密文如下:明文:0x0123456789ABCDEF 密钥:0x133457799BBCDFF1密文:0x85E813540F0AB4054. 结论本实验通过对DES加密算法的实际操作,深入理解了DES加密算法的工作原理和加密过程。
DES加密算法通过对明文的置换、替代和迭代操作,混淆了明文的结构,使得密文的产生与密钥相关。
des算法标准代码

des算法标准代码一、概述DES(数据加密标准)是一种常用的对称加密算法,它使用64位的密钥对数据进行加密和解密。
本标准代码文档旨在提供DES算法的完整实现,以便读者了解其工作原理和实现细节。
二、算法描述1. 密钥生成:DES算法使用一个56位的密钥,通过一系列复杂的算法将其转换为64位的数据。
2. 加密过程:加密过程包括三个步骤:初始置换、分组和迭代。
在迭代过程中,每个分组被替换为新的分组,并使用密钥进行置换和移位操作。
3. 解密过程:解密过程与加密过程类似,但使用与加密时相反的置换和移位操作。
三、代码实现以下是一个简单的Python实现示例:```pythonfrom Crypto.Cipher import DESfrom Crypto.Util.Padding import pad, unpadfrom binascii import hexlify, unhexlifyimport random# 密钥生成函数def generate_key(bit_length=8):key = [0]*64for i in range(bit_length//8):random.shuffle(key[:8]) # 使用随机数填充8字节密钥的一部分 if i != bit_length//8-1: # 最后一位用校验位替代,所以不算进bit_length长度中random.shuffle(key[8:]) # 对剩余字节打乱顺序,以保护剩余部分的秘密性return key.tolist() # 转换为列表便于序列化处理# DES加密/解密函数def des_encrypt(data, key):des = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行加密padded_data = pad(data.encode(), DES.block_size) # 对数据进行填充处理encrypted_data = des.encrypt(padded_data) # 进行加密操作return encrypted_data.hex() # 将加密结果转换为十六进制字符串方便查看def des_decrypt(encrypted_data, key):des = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行解密操作decrypted_data = des.decrypt(unhexlify(encrypted_data)) # 进行解密操作,并将结果解码为原始数据return unpad(decrypted_data).decode() # 将解密结果进行去填充处理,并解码为原始字符串返回```四、使用示例以下是一个简单的使用示例:```python# 生成随机密钥,这里假设使用长度为8字节的密钥,根据实际情况进行修改即可key = generate_key()print("Generated key: {}".format(hexlify(key)))# 要加密的数据(这里使用字符串“Hello World”作为示例)data = "Hello World"print("Original data: {}".format(data))encrypted_data = des_encrypt(data, key) # 对数据进行加密操作,并输出加密结果(十六进制字符串)print("Encrypted {}".format(encrypted_data))decrypted_data = des_decrypt(encrypted_data, key) # 对加密结果进行解密操作,并输出解密结果(原始字符串)print("Decrypted {}".format(decrypted_data))```请注意,这只是一个简单的示例代码,用于演示DES算法的实现和基本用法。
电脑文档加密的几种方法

电脑文档加密的几种方法
电脑文档加密是一种用于保护私有信息安全的行为,目前也是越来越多企业与个人都
采用的安全保护手段。
电脑文档加密有多种方法,本文将介绍以下几种方法。
一、DES算法加密
DES算法(Data Encryption Standard)是一种对称加密算法,DES算法只有一个密钥,可以用于加密和解密同一数据。
DES算法对于电脑文档的加密很有效,特别是对重要
文档的加密,可以很好的保护文档的安全。
AES算法(Advanced Encryption Standard)是美国国家标准局发布的一种对称加密
算法。
AES算法使用长度可变的128位、192位或256位来代表密钥,比DES算法更为安
全强大,能够更快速、更安全地对电脑文档进行加密。
RSA算法(Rivest-Shamir-Adleman)是一种非对称加密算法,RSA算法有两个密钥,
然后用公钥进行加密,再使用私钥进行解密,非常安全,RSA算法可用于网上交易的安全,也可用于电脑文档的加密,特别是比较重要的文档。
四、PGP算法加密
PGP算法(Pretty Good Privacy)是由美国知名企业Symantec发布的电子加密标准,PGP算法可以实现文件的加密和解密,再搭配随机验证,可以将文件传输过程中的内容完
整性保持完整,在电脑文档加密中很安全。
以上就是电脑文档加密的几种常用方法,采用不同的方法可以达到不同标准的安全性能,对于对文档安全要求较高的情况,应该选择比较安全的加密算法。
des加密算法

des加密算法des加密算法是⼀种对称加密算法,通常要求8字节对齐,如果不满⾜8字节,则补全到8字节的整数倍,通常的做法是缺⼏补⼏,⽐如21字节的内容,则需要补三个3./********************************************************** des.h* ⽤户使⽤des算法头⽂件**********************************************************/#ifndef _OPENDESS_H_#define _OPENDESS_H_#ifdef __cplusplusextern "C" {#endif//ab\0defg//⽤户使⽤的函数int DesEnc(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);//⽤户使⽤函数des解密int DesDec(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);#ifdef __cplusplus}#endif#endif/******************************************************** des.c* common des......*******************************************************/#include <stdlib.h>#include <string.h>#include <stdio.h>#include "des.h"/*********************************************************data type definition for Des;**********************************************************/#define EN0 0#define DE1 1#define DES_KEYBYTES 128#define DES_KEYLONGS 32#define DES_BLOCKLEN 8typedef struct {unsigned char ek[DES_KEYBYTES];int ekLen;unsigned char dk[DES_KEYBYTES];int dkLen;unsigned char CbcCtx[DES_BLOCKLEN];} DES_CTX;typedef struct {unsigned char ek1[DES_KEYBYTES];int ek1Len;unsigned char dk1[DES_KEYBYTES];int dk1Len;unsigned char ek2[DES_KEYBYTES];int ek2Len;unsigned char dk2[DES_KEYBYTES];int dk2Len;unsigned char CbcCtx[DES_BLOCKLEN];//int IsFirstBlock;} DES3_CTX;static unsigned char pc1[56] = {56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };static unsigned char pc2[48] = {13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };static unsigned short bytebit[8] = {0200,0100,040,020,010,04,02,01 };static unsigned char totrot[16] = {1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28}; static unsigned long bigbyte[24] = {0x800000L, 0x400000L, 0x200000L, 0x100000L,0x80000L, 0x40000L, 0x20000L, 0x10000L,0x8000L, 0x4000L, 0x2000L, 0x1000L,0x800L, 0x400L, 0x200L, 0x100L,0x80L, 0x40L, 0x20L, 0x10L,0x8L, 0x4L, 0x2L, 0x1L };//insert digitsstatic unsigned long SP1[64] ={0x01010400l,0x00000000l,0x00010000l,0x01010404l,0x01010004l,0x00010404l,0x00000004l,0x00010000l,0x00000400l,0x01010400l,0x01010404l,0x00000400l,0x01000404l,0x01010004l,0x01000000l,0x00000004l,0x00000404l,0x01000400l,0x01000400l,0x00010400l,0x00010400l,0x01010000l,0x01010000l,0x01000404l,0x00010004l,0x01000004l,0x01000004l,0x00010004l,0x00000000l,0x00000404l,0x00010404l,0x01000000l,0x00010000l,0x01010404l,0x00000004l,0x01010000l,0x01010400l,0x01000000l,0x01000000l,0x00000400l,0x01010004l,0x00010000l,0x00010400l,0x01000004l,0x00000400l,0x00000004l,0x01000404l,0x00010404l,0x01010404l,0x00010004l,0x01010000l,0x01000404l,0x01000004l,0x00000404l,0x00010404l,0x01010400l,0x00000404l,0x01000400l,0x01000400l,0x00000000l,0x00010004l,0x00010400l,0x00000000l,0x01010004l };static unsigned long SP2[64]={0x80108020l,0x80008000l,0x00008000l,0x00108020l,0x00100000l,0x00000020l,0x80100020l,0x80008020l,0x80000020l,0x80108020l,0x80108000l,0x80000000l,0x80008000l,0x00100000l,0x00000020l,0x80100020l,0x00108000l,0x00100020l,0x80008020l,0x00000000l,0x80000000l,0x00008000l,0x00108020l,0x80100000l,0x00100020l,0x80000020l,0x00000000l,0x00108000l,0x00008020l,0x80108000l,0x80100000l,0x00008020l,0x00000000l,0x00108020l,0x80100020l,0x00100000l,0x80008020l,0x80100000l,0x80108000l,0x00008000l,0x80100000l,0x80008000l,0x00000020l,0x80108020l,0x00108020l,0x00000020l,0x00008000l,0x80000000l,0x00008020l,0x80108000l,0x00100000l,0x80000020l, 0x00100020l,0x80008020l,0x80000020l,0x00100020l, 0x00108000l,0x00000000l,0x80008000l,0x00008020l, 0x80000000l,0x80100020l,0x80108020l,0x00108000l }; static unsigned long SP3[64]={0x00000208l,0x08020200l,0x00000000l,0x08020008l, 0x08000200l,0x00000000l,0x00020208l,0x08000200l, 0x00020008l,0x08000008l,0x08000008l,0x00020000l, 0x08020208l,0x00020008l,0x08020000l,0x00000208l, 0x08000000l,0x00000008l,0x08020200l,0x00000200l, 0x00020200l,0x08020000l,0x08020008l,0x00020208l, 0x08000208l,0x00020200l,0x00020000l,0x08000208l, 0x00000008l,0x08020208l,0x00000200l,0x08000000l, 0x08020200l,0x08000000l,0x00020008l,0x00000208l, 0x00020000l,0x08020200l,0x08000200l,0x00000000l, 0x00000200l,0x00020008l,0x08020208l,0x08000200l, 0x08000008l,0x00000200l,0x00000000l,0x08020008l, 0x08000208l,0x00020000l,0x08000000l,0x08020208l, 0x00000008l,0x00020208l,0x00020200l,0x08000008l, 0x08020000l,0x08000208l,0x00000208l,0x08020000l, 0x00020208l,0x00000008l,0x08020008l,0x00020200l }; static unsigned long SP4[64]={0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802080l,0x00800081l,0x00800001l,0x00002001l, 0x00000000l,0x00802000l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00800080l,0x00800001l, 0x00000001l,0x00002000l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002001l,0x00002080l, 0x00800081l,0x00000001l,0x00002080l,0x00800080l, 0x00002000l,0x00802080l,0x00802081l,0x00000081l, 0x00800080l,0x00800001l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00000000l,0x00802000l, 0x00002080l,0x00800080l,0x00800081l,0x00000001l, 0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802081l,0x00000081l,0x00000001l,0x00002000l, 0x00800001l,0x00002001l,0x00802080l,0x00800081l, 0x00002001l,0x00002080l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002000l,0x00802080l }; static unsigned long SP5[64]={0x00000100l,0x02080100l,0x02080000l,0x42000100l, 0x00080000l,0x00000100l,0x40000000l,0x02080000l, 0x40080100l,0x00080000l,0x02000100l,0x40080100l, 0x42000100l,0x42080000l,0x00080100l,0x40000000l, 0x02000000l,0x40080000l,0x40080000l,0x00000000l, 0x40000100l,0x42080100l,0x42080100l,0x02000100l, 0x42080000l,0x40000100l,0x00000000l,0x42000000l, 0x02080100l,0x02000000l,0x42000000l,0x00080100l, 0x00080000l,0x42000100l,0x00000100l,0x02000000l, 0x40000000l,0x02080000l,0x42000100l,0x40080100l, 0x02000100l,0x40000000l,0x42080000l,0x02080100l, 0x40080100l,0x00000100l,0x20000000l,0x42080000l, 0x42080100l,0x00080100l,0x42000000l,0x42080100l, 0x02080000l,0x02000100l,0x40000100l,0x00080000l, 0x00080100l,0x02000100l,0x40000100l,0x00080000l, 0x00000000l,0x40080000l,0x02080100l,0x40000100l }; static unsigned long SP6[64]={0x20000010l,0x20400000l,0x00004000l,0x20404010l, 0x20400000l,0x00000010l,0x20404010l,0x00400000l, 0x20004000l,0x00404010l,0x00400000l,0x20000010l, 0x00400010l,0x20004000l,0x20000000l,0x00004010l,0x00000000l,0x00400010l,0x20004010l,0x00004000l,0x00404000l,0x20004010l,0x00000010l,0x20400010l,0x20400010l,0x00000000l,0x00404010l,0x20404000l,0x00004010l,0x00404000l,0x20404000l,0x20000000l,0x20004000l,0x00000010l,0x20400010l,0x00404000l,0x20404010l,0x00400000l,0x00004010l,0x20000010l,0x00400000l,0x20004000l,0x20000000l,0x00004010l,0x20000010l,0x20404010l,0x00404000l,0x20400000l,0x00404010l,0x20404000l,0x00000000l,0x20400010l,0x00000010l,0x00004000l,0x20400000l,0x00404010l,0x00004000l,0x00400010l,0x20004010l,0x00000000l,0x20404000l,0x20000000l,0x00400010l,0x20004010l };static unsigned long SP7[64] = {0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };static unsigned long SP8[64] = {0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };void deskey(unsigned char *key,short edf, unsigned long *kn);void cookey(register unsigned long *raw1, unsigned long *dough);//void cpkey(register unsigned long *into);//void usekey(register unsigned long *from);//void des(unsigned char *inblock,unsigned char *outblock);void scrunch(register unsigned char *outof, register unsigned long *into); void unscrun(register unsigned long *outof, register unsigned char *into); void desfunc(register unsigned long *block,register unsigned long *keys); /***************** DES Function *****************/unsigned long OPENCOMM_DesExpandEncKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesEncKey,unsigned long *ulDesEncKeyLen);unsigned long OPENCOMM_DesExpandDecKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesDecKey,unsigned long *ulDesDecKeyLen);unsigned long OPENCOMM_DesEncRaw(unsigned char *pbDesEncKey,unsigned long ulDesEncKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen);unsigned long OPENCOMM_DesDecRaw(unsigned char *pbDesDecKey,unsigned long ulDesDecKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen);int myic_DESDecrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);int myic_DESEncrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);void deskey(unsigned char *key,short edf, unsigned long *kn){register int i, j, l, m, n;unsigned long pc1m[56],pcr[56];for ( j = 0; j < 56; j++ ){l = pc1[j];m = l & 07;pc1m[j] = (((unsigned long) key[l >> 3] & (unsigned long)bytebit[m] ) ? 1:0); }for ( i = 0;i < 16; i++){if ( edf == DE1 ) m = (15 - i) << 1;else m = i << 1;n = m + 1;kn[m] = kn[n] = 0L;for ( j = 0; j < 28; j++ ){l = j + totrot[i];if ( l < 28 ) pcr[j] = pc1m[l];else pcr[j] = pc1m[l-28];}for (j = 28; j < 56; j++ ){l = j + totrot[i];if ( l < 56 ) pcr[j] = pc1m[l];else pcr[j] = pc1m[l-28];}for ( j = 0; j < 24; j++ ){if ( pcr[pc2[j]] ) kn[m] |= bigbyte[j];if ( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];}}return;}void cookey(register unsigned long *raw1, unsigned long *dough){register unsigned long *cook,*raw0;register int i;cook = dough;for ( i = 0; i < 16; i++, raw1++ ) {raw0 = raw1++;*cook = (*raw0 & 0x00fc0000L) << 6;*cook |= (*raw0 & 0x00000fc0L) << 10;*cook |= (*raw1 & 0x00fc0000L) >> 10;*cook++ |= (*raw1 & 0x00000fc0L) >> 6;*cook = (*raw0 & 0x0003f000L) << 12;*cook |= (*raw0 & 0x0000003fL) << 16;*cook |= (*raw1 & 0x0003f000L) >> 4;*cook++ |= (*raw1 & 0x0000003fL);}return;}void scrunch(register unsigned char *outof, register unsigned long *into) {*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into++ |= (*outof++ & 0xffL);*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into++ |= (*outof & 0xffL);return;}void unscrun(register unsigned long *outof, register unsigned char *into) {*into++ = (unsigned char)((*outof >> 24) & 0xffL);*into++ = (unsigned char)((*outof >> 16) & 0xffL);*into++ = (unsigned char)((*outof >> 8) & 0xffL);*into++ = (unsigned char)( *outof++ & 0xffL);*into++ = (unsigned char)((*outof >> 24) & 0xffL);*into++ = (unsigned char)((*outof >> 16) & 0xffL);*into++ = (unsigned char)((*outof >> 8) & 0xffL);*into = (unsigned char)( *outof & 0xffL);return;}void desfunc(register unsigned long *block,register unsigned long *keys) {register unsigned long fval, work, right, leftt;register int round;leftt = block[0];right = block[1];work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;right ^= work;leftt ^= (work << 4);work = ((leftt >> 16) ^ right) & 0x0000ffffL;right ^= work;leftt ^= (work << 16);work = ((right >> 2) ^ leftt) & 0x33333333L;leftt ^= work;right ^= (work << 2);work = ((right >> 8) ^ leftt) & 0x00ff00ffL;leftt ^= work;right ^= (work << 8);right = ((right << 1) | ((right >>31) & 1L)) & 0xffffffffL;work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = ((leftt << 1) | ((leftt >> 31)&1L)) & 0xffffffffL;for (round = 0; round < 8; round++) {work = (right << 28) | (right >> 4);work ^= *keys++;fval = SP7[ work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = right ^ *keys++;fval |= SP8[ work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];leftt ^= fval;work = (leftt << 28) | (leftt >> 4);work ^= *keys++;fval = SP7[ work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = leftt ^ *keys++;fval |= SP8[ work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];right ^= fval;}right = (right << 31) | (right >> 1);work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = (leftt << 31) | (leftt >> 1);work = ((leftt >> 8) ^ right) & 0x00ff00ffL;right ^= work;leftt ^= (work << 8);work = ((leftt >> 2) ^ right) & 0x33333333L;right ^= work;leftt ^= (work << 2);work = ((right >> 16) ^ leftt) & 0x0000ffffL;leftt ^= work;right ^= (work << 16);work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;leftt ^= work;right ^= (work << 4);*block++ = right;*block = leftt;return;}/*****************************************************************OPENCOMM_DesExpandEncKey : Expand Des Enc Key 扩展des加密密钥Return value:0 : Successother : failedParameters:pbDesKey : 扩展前的DES密钥(8字节) inputulDesKeyLen : 扩展前的DES密钥长度 inputpbDesEncKey : 扩展后的DES加密密钥(128字节) output*ulDesEncKeyLen : 扩展后的DES加密密钥长度 output*****************************************************************/unsigned long OPENCOMM_DesExpandEncKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesEncKey,unsigned long *ulDesEncKeyLen){unsigned long kn[32], dough[32];if (ulDesKeyLen != 8)return 0xEE20;deskey(pbDesKey, EN0, kn);cookey(kn, dough);*ulDesEncKeyLen = DES_KEYBYTES; //32 long = 128 bytesmemcpy(pbDesEncKey, dough, *ulDesEncKeyLen);return 0;}/*****************************************************************OPENCOMM_DesExpandDecKey : Expand Des Dec Key 扩展des解密密钥Return value:0 : Successother : failedParameters:pbDesKey : 扩展前的DES密钥(8字节) inputulDesKeyLen : 扩展前的DES密钥长度 inputpbDesDecKey : 扩展后的DES解密密钥(128字节) output*ulDesDecKeyLen : 扩展后的DES解密密钥长度 output*****************************************************************/unsigned long OPENCOMM_DesExpandDecKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesDecKey,unsigned long *ulDesDecKeyLen){unsigned long kn[32], dough[32];if (ulDesKeyLen != 8)return 0xEE20;deskey(pbDesKey, DE1, kn);cookey(kn, dough);*ulDesDecKeyLen = DES_KEYBYTES; //32 long = 128 bytesmemcpy(pbDesDecKey, dough, *ulDesDecKeyLen);return 0;}/****************************************************************OPENCOMM_DesEncRaw : Des算法加密⼩整块明⽂8字节Return value:0 : Successother : failedParameters:pbDesEncKey : DES加密密钥 inputulDesEncKeyLen : DES加密密钥长度 inputpbInData : 待加密的明⽂ inputulInDataLen : 待加密的明⽂长度 inputpbOutData : 加密后的密⽂ output*ulOutDataLen : 加密后的密⽂长度 output*****************************************************************/unsigned long OPENCOMM_DesEncRaw(unsigned char *pbDesEncKey,unsigned long ulDesEncKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen){unsigned long work[2], ek[DES_KEYLONGS];unsigned char cp[DES_BLOCKLEN];if (ulInDataLen != DES_BLOCKLEN)return 0xEE20;if (ulDesEncKeyLen != DES_KEYBYTES)return 0xEE20;memcpy(cp, pbInData, DES_BLOCKLEN);scrunch(cp,work); // 8 bytes -> 2 longmemcpy(ek, pbDesEncKey, ulDesEncKeyLen);desfunc(work,ek);unscrun(work,cp); // 2 long -> 8 bytesmemcpy(pbOutData, cp, DES_BLOCKLEN);*ulOutDataLen = DES_BLOCKLEN;return 0;}/***************************************************************** OPENCOMM_DesDecRaw : Des算法解密⼩整块密⽂8字节Return value:0 : Successother : failedParameters:pbDesDecKey : DES解密密钥 input ulDesDecKeyLen : DES解密密钥长度 inputpbInData : 待解密的密⽂ inputulInDataLen : 待解密的密⽂长度 inputpbOutData : 解密后的明⽂ output*ulOutDataLen : 解密后的明⽂长度 output*****************************************************************/ unsigned long OPENCOMM_DesDecRaw(unsigned char *pbDesDecKey,unsigned long ulDesDecKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen){unsigned long work[2], dk[DES_KEYLONGS];unsigned char cp[DES_BLOCKLEN];if (ulInDataLen != DES_BLOCKLEN)return 0xEE20;if (ulDesDecKeyLen != DES_KEYBYTES)return 0xEE20;memcpy(cp, pbInData, DES_BLOCKLEN);scrunch(cp,work); // 8 bytes -> 2 longmemcpy(dk, pbDesDecKey, ulDesDecKeyLen);desfunc(work,dk);unscrun(work,cp); // 2 long -> 8 bytesmemcpy(pbOutData, cp, DES_BLOCKLEN);// des_enc(pbDesEncKey, pbInData, pbOutData);*ulOutDataLen = DES_BLOCKLEN;return 0;}/********************* DES *********************/int myic_DESEncrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){unsigned char DesKeyBuf[32];unsigned char DesEncKeyBuf[128];int EncKeyLen, KeyLen = 0;int retval = 0, loops, i;if(nInDataLen%8 != 0)return 0xEE20;if(nDesKeyLen != 8)return 0xEE20;KeyLen = nDesKeyLen;memcpy(DesKeyBuf, pDesKey, nDesKeyLen);retval = OPENCOMM_DesExpandEncKey(DesKeyBuf, KeyLen, DesEncKeyBuf, (unsigned long *)&EncKeyLen);if(retval != 0)return retval;loops = nInDataLen/8;for(i = 0; i < loops; i++){retval = OPENCOMM_DesEncRaw(DesEncKeyBuf, EncKeyLen, pInData + i*8, 8, pOutData + i*8, (unsigned long *)pOutDataLen);if(retval != 0)return retval;}*pOutDataLen = nInDataLen;return retval;}int myic_DESDecrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){unsigned char DesKeyBuf[32];unsigned char DesDecKeyBuf[128];int DecKeyLen, KeyLen = 0;int retval = 0, loops, i;if(nInDataLen%8 != 0)return 0xEE20;if(nDesKeyLen != 8)return 0xEE20;KeyLen = nDesKeyLen;memcpy(DesKeyBuf, pDesKey, nDesKeyLen);retval = OPENCOMM_DesExpandDecKey(DesKeyBuf, KeyLen, DesDecKeyBuf, (unsigned long *)&DecKeyLen);if(retval != 0)return retval;loops = nInDataLen/8;for(i = 0; i < loops; i++){retval = OPENCOMM_DesDecRaw(DesDecKeyBuf, DecKeyLen, pInData + i*8,8, pOutData + i*8, (unsigned long *)pOutDataLen);if(retval != 0)return retval;}*pOutDataLen = nInDataLen;return retval;}//对称明⽂数据打padingvoid CW_dataPadAdd(int tag, unsigned char *date, unsigned int dateLen,unsigned char **padDate, unsigned int *padDateLen){int i, padLen;unsigned char *pTmp = NULL;pTmp = (unsigned char *)malloc(dateLen+24);if (pTmp == NULL){*padDate = NULL;return ;}memset(pTmp, 0, dateLen+24);memcpy(pTmp, date, dateLen);if (tag == 0){padLen = 8 - dateLen % 8;for (i=0; i<padLen; i++){pTmp[dateLen+i] = (char)padLen;}*padDateLen = dateLen + padLen;}else{padLen = 16 - dateLen % 16;for (i=0; i<padLen; i++){pTmp[dateLen+i] = (char)padLen;}}*padDateLen = dateLen + padLen;*padDate = pTmp;}#define USER_PASSWORD_KEY "abcd1234"//数据加密int DesEnc(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;unsigned char *padDate = NULL;unsigned int padDateLen = 0;CW_dataPadAdd(0, pInData, (unsigned int )nInDataLen, &padDate, &padDateLen);rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), padDate, (int)padDateLen, pOutData, pOutDataLen);if (rv != 0){if (padDate != NULL){free(padDate);}return rv;}if (padDate != NULL){free(padDate);}return 0;}//数据加密int DesEnc_raw(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;unsigned char *padDate = NULL;unsigned int padDateLen = 0;rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, (int)nInDataLen, pOutData, pOutDataLen);if (rv != 0){return rv;}return 0;}//解密分配内存错误#define ERR_MALLOC 20//密码长度不是8的整数倍, 不合法#define ERR_FILECONT 20//⽤户使⽤函数des解密int DesDec(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;char padChar;unsigned char *tmpPlain = NULL;tmpPlain = (unsigned char *)malloc(nInDataLen+24);if (tmpPlain == NULL){return ERR_MALLOC;}memset(tmpPlain, 0, nInDataLen+24);//解密rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, tmpPlain, pOutDataLen);if (rv != 0){if (tmpPlain != NULL) free(tmpPlain);return rv;}//去padingpadChar = tmpPlain[*pOutDataLen - 1];if ( (int)padChar<=0 || (int)padChar>8) //异常处理{if (tmpPlain) free(tmpPlain);return ERR_FILECONT;}*pOutDataLen = *pOutDataLen - (int)padChar;//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);memcpy(pOutData, tmpPlain, *pOutDataLen);if (tmpPlain) free(tmpPlain);return 0;}//⽤户使⽤函数des解密int DesDec_raw(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;//char padChar;//unsigned char *tmpPlain = NULL;/*tmpPlain = (unsigned char *)malloc(nInDataLen+24);if (tmpPlain == NULL){return ERR_MALLOC;}memset(tmpPlain, 0, nInDataLen+24);*///解密rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, pOutData, pOutDataLen);if (rv != 0){//if (tmpPlain != NULL) free(tmpPlain);return rv;}/*//去padingpadChar = tmpPlain[*pOutDataLen - 1];if ( (int)padChar<=0 || (int)padChar>8) //异常处理{if (tmpPlain) free(tmpPlain);return ERR_FILECONT;}*pOutDataLen = *pOutDataLen - (int)padChar;//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);memcpy(pOutData, tmpPlain, *pOutDataLen);if (tmpPlain) free(tmpPlain);*/return 0;}。
DES加密算法与解密(带流程图)

DES加密算法与解密(带流程图)一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6,64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7};const static char Final_Table[] = { //最终置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25};const static char S_Box[8][64] = {//s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10,14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}const static char Rar_Table[] = { //压缩置换14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32};const static char Exp_Table[] = { //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits)//位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++)hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2; }for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1]; BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) ) return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!"; char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:Enter = 待加密文本分割Enter ,8字节为一段,不足补加,段数为N 初始化:*Print ,i=0,j=0文本第i 段,转为二进制64位初始置换(IP_Table )文本段分为左右两部分左部分(32位)右部分(32)输入8字节密钥转为二进制64位密钥压缩KeyRar_Table (56位)形成16轮密钥合并形成子密钥(48位)S 置换(S_Box )P 置换(P_Table )左右交换,j++最终置换(Final_Table )J<16扩展置换(Exp_Table )i<N异或异或NoYes存入*Print ,i++DES 加密过程结束,输出Print YesNoDES 解密过程为以上逆过程。
DES加密算法

DES加密算法1950年代末至1970年代初,密码学家发现了许多消息传递系统被成功入侵的案例。
为了应对这种威胁,美国国家安全局(NSA)与IBM公司合作开发了一种新的加密算法,即数据加密标准(Data Encryption Standard,简称DES)。
DES在20世纪70年代末被正式采纳,并成为许多国家及组织使用的标准加密算法,它不仅安全可靠,而且非常高效。
本文将对DES加密算法进行详细介绍。
一、DES加密算法简介DES加密算法是一种对称密钥算法,使用相同的密钥进行加密和解密。
在加密和解密过程中,DES算法将数据分成64位大小的数据块,并进行一系列置换、替换、混淆和反混淆等操作。
DES算法共有16轮运算,每轮运算都与密钥有关。
最终输出的密文与64位的初始密钥相关联,只有使用正确的密钥才能解密并还原原始数据。
二、DES加密算法的原理DES算法的核心是通过一系列的置换、替换和混淆技术对数据进行加密。
以下是DES算法的主要步骤:1. 初始置换(Initial Permutation)DES算法首先将明文进行初始置换,通过一系列规则将64位明文重新排列。
2. 轮函数(Round Function)DES算法共有16个轮次,每轮都包括以下几个步骤:a) 拓展置换(Expansion Permutation)将32位的数据扩展为48位,并进行重新排列。
b) 密钥混淆(Key Mixing)将48位的数据与轮次对应的子密钥进行异或运算。
c) S盒代替(S-box Substitution)将48位的数据分为8个6位的块,并根据S盒进行替换。
S盒是一个具有固定映射关系的查找表,用于增加加密算法的复杂性和安全性。
d) 置换函数(Permutation Function)经过S盒代替后,将得到的数据再进行一次置换。
3. 左右互换在每轮的运算中,DES算法将右半部分数据与左半部分进行互换,以实现加密算法的迭代。
4. 逆初始置换(Inverse Initial Permutation)最后,DES算法对经过16轮运算后的数据进行逆初始置换,得到最终的密文。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北京工业大学网络与信息安全概论学院:专业:指导老师:姓名:学号:目录目录 (2)一、DES算法的基本原理 (3)1.1背景介绍 (3)1.2加密原理 (3)二、DES算法的详细步骤 (4)2.1加密详细步骤 (4)2.2压缩置换到56位 (5)2.3 C0和D0的分类 (6)2.4循环左移 (6)2.5压缩置换 (7)三、DES算法的实现 (7)3.1详细设计 (8)3.1.2加密/解密文件的预览 (8)3.2文件的加密/解密 (9)3.3系统测试 (11)3.4总结 (14)一、DES算法的基本原理1.1背景介绍1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES-Data Encryption Standard)。
DES (Data Encryption Standard),是IBM在上个世纪70年代开发的单密钥对称加解密算法。
该算法利用一个56+8奇偶校验位(第8, 16, 24, 32, 40, 48, 56, 64位)=64位的密钥对以64位为单位的块数据进行加解密。
1.2加密原理DES算法是这样工作的:如Mode为加密,则用Key 去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。
在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。
这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性,这正是现在金融交易网络的流行做法。
二、DES算法的详细步骤2.1加密详细步骤a.明文先P置换分成L0 和R0。
b.R0通过扩展置换E从32位扩展为48位。
c.扩展后与K1异或。
d.异或结果通过S盒子转换成32位。
e.这32位再通过P置换输出32位。
f.最后,P盒置换的结果与左半部分进行异或运算,然后将左右两部分交换,之后进入下一轮迭代。
g.在完成完全相同的16轮运算后,将得到的两部分数据合在一起,将L16与R16的位置交换,再经过一个末置换函数IP-1即可得到64位的密文。
图1为DES算法的理论图解:图1 DES加密算法流程2.2压缩置换到56位通过压缩置换后64位的密钥中的奇偶校验位(第8, 16, 24, 32, 40, 48, 56, 64位)就会被去掉。
对K(64位)使用PC-1(8×7)进行置换,去掉了8个校验位。
表1 密钥置换函数PC-1(8x7)PC-157 49 41 33 25 1791 58 50 42 34 26 1810 2 59 51 43 35 2719 11 3 60 52 44 3663 55 47 39 31 23 157 62 54 46 38 30 2214 6 61 53 45 37 2921 13 5 28 20 12 42.3 C0和D0的分类经过PC-1置换后,将其置换的输出再分为前28位C0和后28位D0两部分。
图2 密钥置换输出的分法2.4循环左移再将C0和D0两部分按照下面步骤进行16轮的循环左移。
迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 C1和D1分别为C0和D0左移1位……C3和D3分别为C2和D2左移2位……C16和D16分别为C15和D15左移1位。
2.5压缩置换进行一轮循环左移,就按照表4进行压缩置换,得到一个子密钥。
即置换后的输出数据的位数要比置换前输入的位数要少,原来的8行7列共56位数据被压缩成8行6列48位数据。
在压缩置换过程中,第9、18、22、25、35、38、43、54共8位数据被丢掉。
最终得到所有16个子密钥,每个48位。
置换过程如图3所示。
图3 子密钥Kn的产生Kn(48位) = PC-2( CnDn(56位) )三、DES算法的实现采用MFC实现DES加密算法。
可以对导入的文档实现加密解密,加密或解密后的文件存储路径可以自定义。
图4是主界面:图4 系统主界面如果输入的密钥长度大于8,程序自动启动3重DES加密算法。
用户可以自动设置加密/解密后存储文件的路径。
也可以在不打开文件的情况下预览加密/解密前后的文件内容。
3.1详细设计3.1.1文件的选择与存储打开程序后,首先要选择加密/解密的文件,图4中的和这两个按钮可以实现这个功能,文件载入后设置了密钥,即可实现对文件的加密/解密。
主要是用CFileDialog实现的。
CFileDialog FileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter );3.1.2加密/解密文件的预览用户可以在不打开加密/解密文件的情况下,对文件的内容进行预览。
界面中的和按钮来实现这个功能。
核心代码如下:CString strText = ""; CString szLine = ""; CStdioFile file;file.Open(m_FileEncryptOut,CFile::modeRead);while( file.ReadString( szLine ) ){strText += szLine; }AfxMessageBox(strText); file.Close();3.2文件的加密/解密对于文件的加密和解密是在一个定义时没有制定大小的缓冲区里面进行的。
缓冲区的大小是由读入文件的大小决定的。
但是它的大小总是8的倍数,当读入数据的大小不是8的整数倍时,它的大小总比读入的文件要大一点点。
len=_lread(fh_in,databuf,BUFSIZE);//返回值为读入文件的数据大小len = ((len+7)>>3)<<3;//将len变为8的倍数当输入的密钥大于8位时,系统自动启动3重DES加密算法。
if( !Is3DES ){ // 1次DESfor(int i=0,j=len>>3; i<j; ++i){DES(Out,In,&SubKey[0],ENCRYPT);Out += 8; In += 8;}}else{ // 3次DES E-D-Efor(int i=0,j=len>>3; i<j; ++i){DES(Out,In, &SubKey[0],ENCRYPT);DES(Out,Out,&SubKey[1],DECRYPT);DES(Out,Out,&SubKey[0],ENCRYPT);Out += 8; In += 8;}}同样的,在解密的时候,若输入的密钥大于8位时,系统自动启动3重DES 算法。
加密和解密算法主要实现都是DES(char Out[8],char In[8],const PSubKey pSubKey,bool Type)函数来实现。
其中Type—ENCRYPT:加密,DECRYPT:解密,文件加密还是解密就看Type的值。
核心代码如下:UpdateData(true);HFILE fh_out,fh_in;//输入输出文件句柄fh_in=_lopen(m_FileEncrypt,OF_READ);fh_out=_lcreat(m_FileEncryptOut,0);long len;// 读取明文到缓冲区while( (len=_lread(fh_in,databuf,BUFSIZE)) >0 ){I=len%8;//对明文长度求余// 设置子密钥if(m_KeyEncrypt.GetLength()>=16)m_KeyEncrypt=m_KeyEncrypt.Left(16);m_des.SetSubKey(m_KeyEncrypt);// 将缓冲区长度变为8的倍数len = ((len+7)>>3)<<3;// 在缓冲区中加密m_des.Encrypt(databuf,databuf,len);// 将密文写入输出文件if(I==0)_lwrite(fh_out,databuf,len);else_lwrite(fh_out,databuf,len-8+I);}_lclose(fh_in);_lclose(fh_out);解密过程与加密过程一样,只不过解密过程调用的函数是m_des.Decrypt()。
加密的m_des.encrypt()与解密的m_des.Decrypt()这两个函数都是通过调用DES()函数来实现对文件的加密解密的。
值得注意的是,当明文或者是要解密的密文的长度不是8的倍数时,缓冲区这个时候的长度总是比输入的实际长度要大一些,这样缓冲区中多出来的部分默认值是0,他们也会被加密或者解密。
所以每做完一次加密或解密时,总要判断明文的长度是否为8的倍数,如果不是在存储加密/解密后的文件时,应该去掉这些多余的部分。
if(I==0)_lwrite(fh_out,databuf,len);else_lwrite(fh_out,databuf,len-8+I);3.3系统测试由于加密和解密的过程类似,所以我们在这里仅对加密过程进行测试。
在一个名为“test.txt”的文本文档里面输入“Who am I?”,对系统的加密功能进行测试,密钥为“12”。
图5,图6,图7为测试后的截图。
图5 点击加密按钮后的提示图6 点击显示密文按钮后的提示图7 点击显示明文按钮后的提示当你在没有选择任何文档或者没有填写既要的情况下点击加密按钮或者想查看明文/密文时,系统会报错。
如图8,图9和图10所示。
图8 直接点击加密按钮后的提示图9 直接点击显示密文按钮后的提示图9 直接点击显示明文按钮后的提示3.4总结在理解了DES算法的基本原理后,对DES算法的基本原理和详细步骤进行的阐述。
通过几天的努力,用MFC实现了DES算法的加密解密过程。
但是程序界面有待改进,可以在实现了加密解密的基础上直接现实出明文和密文。
其他地方也需要美化。