一、DES算法介绍

来源:互联网 发布:网络公墓 编辑:程序博客网 时间:2024/05/20 18:00

一、DES算法介绍
DES( Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。以下简要地介绍该算法的步骤。

A. 密钥生成
1、取得密钥

从用户处取得一个64位长的密码key ,去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥。
2、 等分密钥

把生成的56位输入密钥分成均等的A,B两部分,每部分为28位,参照表1和表2把输入密钥的位置填入相应的位置。 按表1所示A的第一位为输入的64位密钥的第57位,A的第2位为64位密钥的第49位,……,依此类推,A的最后一位是64位密钥的第36位。
3、 密钥的移位

DES算法的密钥是经过16次迭代得到一组密钥的,把生成的A,B视为迭代的起始密钥,表3显示在第I次迭代时密钥循环左移的位数。 比如在第1次迭代时密钥循环左移1位,第3次迭代时密钥循环左移2位。 第9次迭代时密钥循环左移1位,第14次迭代时密钥循环左移2位。
4、 密钥的选取

 


把第I次迭代生成的两个28位长的密钥为合并,按表4所示k的第一位为56位密钥的第14位,k的第2位为56位密钥的第17位,……,依此类推,k的最后一位是56位密钥的第32位。 这样就得到子密钥K[I]。
5、迭代
DES算法密钥生成需要进行16次迭代,在完成16次迭代前,循环执行密钥的移位和密钥的选取。最终形成16个子密钥:K[0],K[1],……,[15]。

B. 数据的加密操作
1、 取得数据
把明文数据分成64位的数据块,不够64位的数据块以适当的方式补足。
2、 初始换位

按表5所示,把输入的64位数据的原第58位换到第一位,原第50位换到第二位,……,依此类推,最后的得到新的64位数据。
3 、数据扩展
第一次迭代以刚生成的新数据作为输入数据,第I(I > 1)次迭代以第I-1次的64位输出数据为输入数据,把64位数据按位置等分成左右两部分:left和right。
保持left不变,根据表6把right由32位扩展成48位

把扩展后的48位right与第I次迭代生成的48位子密钥,进行按位异或原是,形成一个新的48位的right。
4、 数据压缩
上面形成的48位的right值, 需要把它转换成32位的right值。把right视为由8个6位二进制组成, a,b,……,h都是6位,强制转换成10进制整数的值都不大于64 ,a,b,……,h转成10进制整数后,在对应的表中根据转换后整数值,取得对应位置的替代值, a对应表7.1,b对应表7.2,……,h对应表7.8。每6位用一个4位替换这样就完成了从48位向32位数据的转换。比如:
a = 32 ,那么到表7.1中找到32的位置,把对应的替代值0x8赋给a;
d = 53 ,那么到表7.4中找到的位置,把对应的替代值 0x3赋给d ;
g = 16, 那么到表7.7中找到16的位置,把对应的替代值0xa赋给g;

5 、数据换位
把上面形成的32位right,根据表8进行转换。数据的原第16位换到第一位,原第7位换到第二位,……,依此类推,最后得到新的32位数据。

6 、交换数据
把right 和left按位异或运算后的值赋给right,然后将本轮输入的原始right值赋给left。
7 、迭代
DES算法需要进行16次迭代,在完成16次迭代前,把第I-1次得到的left和right的值作为第I次的输入数据,重复3,4,5,6的步骤,但是有一点要记住:在步骤3中第I次迭代要选择第I次迭代生成的子密钥与数据进行按位异或运算。
8 、数据整理

为保证加密和解密的对称性,DES算法的前15次迭代每完成一次迭代都要交换left和right的值,第16次迭代不交换两者的数值。 到此把32位的left和right合并成64位的数据。
根据表9重新调整位置。数据的原第40位换到第一位,原第8位换到第二位,……,依此类推,最后的得到新的64位数据,即为密文。
C. 数据的解密
数据解密的算法与加密算法相同,区别在于和数据进行按位异或运算时,子密钥的使用顺序不同,在加密中是按照第I次迭代就采用第I次迭代生成的子密钥进行异或,而解密时第I次迭代就采用第15-I次迭代生成的密钥和数据进行异或。

 

二、算法的实现
以下是用c语言编写的基于DES算法的核心加密解密程序的接口函数。
1、加密函数
unsigned char enDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],/
unsigned char* outdata,unsigned long* outlen);//加密
功能:本函数实现了根据初始密钥生成16个子密钥。把明文数据分割成64位的数据块,逐块实现16次循环迭代加密。密文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是最简单的ECB模式的DES加密。
参数:
indata:指向明文数据的指针。
inlen:明文数据的长度。
key:用户输入的密钥。
outdata:存放密文数据的指针。
outlen:传入outdata内存的大小,传出密文数据的长度。
返回值:1-成功,0-失败。
unsigned char enDES_cbc(unsigned char* indata,unsigned long inlen,unsigned char key[8],/
        unsigned char* outdata,unsigned long* outlen,unsigned char* iv);
功能:本函数实现了根据初始密钥生成16个子密钥。把明文数据分割成64位的数据块,逐块实现16次循环迭代加密。密文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是CBC模式的DES加密。
参数:
indata:指向明文数据的指针。
inlen:明文数据的长度。
key:用户输入的密钥。
outdata:存放密文数据的指针。
outlen:传入outdata内存的大小,传出密文数据的长度。
返回值:1-成功,0-失败。
unsigned char enY5DES(gYan5DES* y5);
功能:本函数是专门为研五封装的加密接口。内部调用了enDES函数和base64编码的函数。
参数:
Y5:结构体指针。
返回值:1-成功,0-失败。
2、解密函数
unsigned char unDES(unsigned char* indata,unsigned long inlen,unsigned char key[8],/
        unsigned char* outdata,unsigned long* outlen);//解密
功能:本函数实现了根据初始密钥生成16个子密钥。把密文数据分割成64位的数据块,逐块实现16次循环迭代解密。明文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是最简单的ECB模式的DES加密。
参数:
indata:指向密文数据的指针。
inlen:密文数据的长度。
key:用户输入的密钥。
outdata:存放明文数据的指针。
outlen:传入outdata内存的大小,传出明文数据的长度。
返回值:1-成功,0-失败。
unsigned char* unDES_cbc(unsigned char* data,unsigned char* key,/
        unsigned long inlen,unsigned long* outlen,char* iv);//解密
功能:本函数实现了根据初始密钥生成16个子密钥。把密文数据分割成64位的数据块,逐块实现16次循环迭代解密。明文数据放指针outdata所指向的内存中,它必须提前分配,并要求足够大(>inlen+8)。这是CBC模式的DES加密。
参数:
data:指向密文数据的指针。
key:用户输入的密钥。
inlen:密文数据的长度。
outlen:传入outdata内存的大小,传出明文数据的长度。
iv:初始向量。
返回值:1-成功,0-失败。
unsigned char unY5DES(gYan5DES* y5);
功能:本函数是专门为研五封装的解密接口。内部调用了base64解码的函数和unDES函数。
参数:
Y5:结构体指针。
返回值:1-成功,0-失败。
3、密钥生成函数
void randKey(unsigned char key[8]);//生成随机密钥
功能: 本函数调用编译器的参数随机数的函数,生成一个64位的随机密钥。由于随机数参产生器产生的不是真正的随机数,所以这种方法不可靠。
参数:
key[]:存放8字节二进制密钥的数组。
返回值:无返回值。
4、加密解密公共函数
unsigned char comDES(unsigned char in[8],unsigned char out[8],
        unsigned char subkey[16][8],unsigned char flg);
功能:根据加密解密标志flg和16个48位的子密钥subkey。把64位的初始数据in,加密解密成64位的新数据out。
5、生成子密钥函数
void genKey(unsigned char*,unsigned char[16][8]);
功能:根据用户给出的一个64位密钥,产生16个48位的子密钥。
6、S盒代替函数
void sReplace(unsigned char*) ;
功能:实现S盒代替,把48位的数据压缩到32位。

 

 

类别:c/c++/c# | 浏览(301) | 评论 (2)
原创粉丝点击