des算法实现课程设计.docx

上传人:b****6 文档编号:8093803 上传时间:2023-01-28 格式:DOCX 页数:21 大小:143.90KB
下载 相关 举报
des算法实现课程设计.docx_第1页
第1页 / 共21页
des算法实现课程设计.docx_第2页
第2页 / 共21页
des算法实现课程设计.docx_第3页
第3页 / 共21页
des算法实现课程设计.docx_第4页
第4页 / 共21页
des算法实现课程设计.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

des算法实现课程设计.docx

《des算法实现课程设计.docx》由会员分享,可在线阅读,更多相关《des算法实现课程设计.docx(21页珍藏版)》请在冰豆网上搜索。

des算法实现课程设计.docx

des算法实现课程设计

通达学院课程设计Ⅱ报告

(2016/2017学年第1学期)

 

题目:

DES算法实现

 

专业计算机科学与技术(信息安全)

学生姓名

班级学号

指导教师王波

指导单位计算机学院信息安全系

日期

评分细则

评分项

优秀

良好

中等

遵守机房规章制度

上机时的表现

学习态度

程序准备情况

程序设计能力

团队合作精神

课题功能实现情况

算法设计合理性

用户界面设计

报告书写认真程度

内容详实程度

文字表达熟练程度

回答问题准确度

简短评语

 

教师签名:

年月日

评分等级

备注

评分等级有五种:

优秀、良好、中等、及格、不及格

DES算法的实现

一、课题内容和要求

对称加密就是加密和解密所用的密钥是一样的,加密的强度很大程度上在于密钥的强度以及加密算法的保密,最常见的对称加密算法有DES、IDEA、RC4、RC5等。

本设计题要求实现DES加密和解密算法,能对文件实现加解密。

二、对设计要求的理解

DES是一个分组密码算法,使用64位密钥(除去8位奇偶校验,实际密钥长度为56位)对64比特的数据分组(二进制数据)加密,产生64位密文数据。

DES是一个对称密码体制,加密和解密使用同意密钥,解密和加密使用同一算法(这样,在硬件与软件设计时有利于加密单元的重用)。

DES的所有的保密性均依赖于密钥。

程序主要采取对数据的位操作的形式,把明密文文件中的内容以字节为单位读取,每次读取8个byte共65bits,然后使用标准DES的算法依次对读取的64bits明密文进出加解密处理。

文件的路径的输入有比较严格的格式约束。

如:

盘符名:

\\文件名.txt格式错误则会导致文件打开失败,不能进行加解密操作。

三、概要设计

这个程序主要是DES算法部分的加密和解密,还有后面对文件的操作。

程序主要流程图如下:

图-1程序流程图

这个程序的关键在DES算法的操作,主要有下的主要步骤:

1.初始置换IP;

2.子密钥Ki的获取;

3.密码函数f;

4.尾置换IP-1;

下面是具体的几个过程:

1)初始置换IP

这一部分很简单,IP(initialpermutation)是一个8x8的置换表:

intIP[]={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};

根据表中的规定,将输入的64位明文重新进行排序,即将第58位放到第1位,第50位放到第2位……以此类推。

初始置换以后得到的是一个64位的输出。

2)子密钥Ki的获取

用户输出的密钥是64位的,根据密钥置换表PC-1,将64位变成56位密钥。

(去掉了奇偶校验位)将PC-1置换得到的56位密钥,分为前28位C0和后28位D0,分别对它们进行循环左移,C0左移得到C1,D0左移得到D1。

将C1和D1合并成56位,然后通过PC-2表进行压缩置换,得到当前这一轮的48位子密钥K1。

然后对C1和D1进行左移和压缩置换,获取下一轮的子密钥……一共进行16轮,得到16个48位的子密钥。

3)密码函数f

●密码函数f(R,K)接受两个输入:

32位的数据和48位的子密钥。

然后:

●通过表E进行扩展置换,将输入的32位数据扩展为48位;

●将扩展后的48位数据与48位的子密钥进行异或运算;

●将异或得到的48位数据分成8个6位的块,每一个块通过对应的一个S表产生一个4位的输出。

其中,每个S表都是4行16列。

具体的置换过程如下:

把6位输入中的第1位和第6位取出来行成一个两位的二进制数x,作为Si表中的行数(0~3);把6位输入的中间4位构成另外一个二进制数y,作为Si表的列数(0~15);查出Si表中x行y列所对应的整数,将该整数转换为一个4位的二进制数。

把通过S表置换得到的8个4位连在一起,形成一个32位的数据。

然后将该32位数据通过表P进行置换(称为P-置换),置换后得到一个仍然是32位的结果数据,这就是f(R,K)函数的输出。

4)尾置换IP-1

合并L16和R16得到一个64位的数据,再经过尾置换后得到的就是64位的密文。

注意:

要将L16和R16合并成R16L16(即左右互换)。

尾置换表IP-1如下:

intIP_1[]={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};

四、关键技术难点分析

在DES算法的实现中,我用C++STL中的bitset来操作二进制位。

下面是对一个64位数据进行加密解密的源代码:

bitset<64>key;//64位密钥

bitset<48>subKey[16];//存放16轮子密钥

//初始置换表

intIP[]={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};

//结尾置换表

intIP_1[]={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};

/*------------------下面是生成密钥所用表-----------------*/

//密钥置换表,将64位密钥变成56位

intPC_1[]={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};

//压缩置换,将56位密钥压缩成48位子密钥

intPC_2[]={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};

//每轮左移的位数

intshiftBits[]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

/*------------------下面是密码函数f所用表-----------------*/

//扩展置换表,将32位扩展至48位

intE[]={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,1};

//S盒,每个S盒是4x16的置换表,6位->4位

intS_BOX[8][4][16]={

{

{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}

},

{

{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,6,9,11,5},

{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},

{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}

},

{

{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},

{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},

{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},

{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}

},

{

{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},

{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},

{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},

{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}

},

{

{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}

},

{

{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}

},

{

{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}

},

{

{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}

}

};

//P置换,32位->32位

intP[]={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};

/**********************************************************************/

/**/

/*下面是DES算法实现*/

/**/

/**********************************************************************/

/**

*密码函数f,接收32位数据和48位子密钥,产生一个32位的输出

*/

bitset<32>f(bitset<32>R,bitset<48>k)

{

bitset<48>expandR;

//第一步:

扩展置换,32->48

for(inti=0;i<48;++i)

expandR[47-i]=R[32-E[i]];

//第二步:

异或

expandR=expandR^k;

//第三步:

查找S_BOX置换表

bitset<32>output;

intx=0;

for(inti=0;i<48;i=i+6)

{

introw=expandR[47-i]*2+expandR[47-i-5];

intcol=expandR[47-i-1]*8+expandR[47-i-2]*4+expandR[47-i-3]*2+expandR[47-i-4];

intnum=S_BOX[i/6][row][col];

bitset<4>binary(num);

output[31-x]=binary[3];

output[31-x-1]=binary[2];

output[31-x-2]=binary[1];

output[31-x-3]=binary[0];

x+=4;

}

//第四步:

P-置换,32->32

bitset<32>tmp=output;

for(inti=0;i<32;++i)

output[31-i]=tmp[32-P[i]];

returnoutput;

}

/**

*对56位密钥的前后部分进行左移

*/

bitset<28>leftShift(bitset<28>k,intshift)

{

bitset<28>tmp=k;

for(inti=27;i>=0;--i)

{

if(i-shift<0)

k[i]=tmp[i-shift+28];

else

k[i]=tmp[i-shift];

}

returnk;

}

/**

*生成16个48位的子密钥

*/

voidgenerateKeys()

{

bitset<56>realKey;

bitset<28>left;

bitset<28>right;

bitset<48>compressKey;

//去掉奇偶标记位,将64位密钥变成56位

for(inti=0;i<56;++i)

realKey[55-i]=key[64-PC_1[i]];

//生成子密钥,保存在subKeys[16]中

for(intround=0;round<16;++round)

{

//前28位与后28位

for(inti=28;i<56;++i)

left[i-28]=realKey[i];

for(inti=0;i<28;++i)

right[i]=realKey[i];

//左移

left=leftShift(left,shiftBits[round]);

right=leftShift(right,shiftBits[round]);

//压缩置换,由56位得到48位子密钥

for(inti=28;i<56;++i)

realKey[i]=left[i-28];

for(inti=0;i<28;++i)

realKey[i]=right[i];

for(inti=0;i<48;++i)

compressKey[47-i]=realKey[56-PC_2[i]];

subKey[round]=compressKey;

}

}

/**

*工具函数:

将char字符数组转为二进制

*/

bitset<64>charToBitset(constchars[8])

{

bitset<64>bits;

for(inti=0;i<8;++i)

for(intj=0;j<8;++j)

bits[i*8+j]=((s[i]>>j)&1);

returnbits;

}

/**

*DES加密

*/

bitset<64>encrypt(bitset<64>&plain)

{

bitset<64>cipher;

bitset<64>currentBits;

bitset<32>left;

bitset<32>right;

bitset<32>newLeft;

//第一步:

初始置换IP

for(inti=0;i<64;++i)

currentBits[63-i]=plain[64-IP[i]];

//第二步:

获取Li和Ri

for(inti=32;i<64;++i)

left[i-32]=currentBits[i];

for(inti=0;i<32;++i)

right[i]=currentBits[i];

//第三步:

共16轮迭代

for(intround=0;round<16;++round)

{

newLeft=right;

right=left^f(right,subKey[round]);

left=newLeft;

}

//第四步:

合并L16和R16,注意合并为R16L16

for(inti=0;i<32;++i)

cipher[i]=left[i];

for(inti=32;i<64;++i)

cipher[i]=right[i-32];

//第五步:

结尾置换IP-1

currentBits=cipher;

for(inti=0;i<64;++i)

cipher[63-i]=currentBits[64-IP_1[i]];

//返回密文

returncipher;

}

/**

*DES解密

*/

bitset<64>decrypt(bitset<64>&cipher)

{

bitset<64>plain;

bitset<64>currentBits;

bitset<32>left;

bitset<32>right;

bitset<32>newLeft;

//第一步:

初始置换IP

for(inti=0;i<64;++i)

currentBits[63-i]=cipher[64-IP[i]];

//第二步:

获取Li和Ri

for(inti=32;i<64;++i)

left[i-32]=currentBits[i];

for(inti=0;i<32;++i)

right[i]=currentBits[i];

//第三步:

共16轮迭代(子密钥逆序应用)

for(intround=0;round<16;++round)

{

newLeft=right;

right=left^f(right,subKey[15-round]);

left=newLeft;

}

//第四步:

合并L16和R16,注意合并为R16L16

for(inti=0;i<32;++i)

plain[i]=left[i];

for(inti=32;i<64;++i)

plain[i]=right[i-32];

//第五步:

结尾置换IP-1

currentBits=plain;

for(inti=0;i<64;++i)

plain[63-i]=currentBits[64-IP_1[i]];

//返回明文

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 思想汇报心得体会

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1