C语言实现DES算法实验报告.docx
- 文档编号:7762510
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:18
- 大小:23.20KB
C语言实现DES算法实验报告.docx
《C语言实现DES算法实验报告.docx》由会员分享,可在线阅读,更多相关《C语言实现DES算法实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
C语言实现DES算法实验报告
xx工程大学
实验报告
(2015-2016学年第一学期)
报告题目:
DES加密算法
课程名称:
密码学B
任课教员:
专业:
学号:
姓名:
二O一六年一月十八日
一、课程概述
目的:
培养学员的编程能力,理解算法原理。
要求:
给出DES算法的软件实现,测试DES的加密速度。
二、设计思路
使用C++语言进行编程,简化了输入输出语句。
预处理时加入了iostream包。
使用了std名字空间。
加密时程序输入的明文是8个ascii码,生成一个16个16进制数的密文。
脱密时程序输入的密文是16个16进制数,生成一个8个ascii码的明文。
加脱密所用密钥均由16个16进制数组成。
其中16进制数全部使用大写字母。
程序中大量使用了的布尔数组,一个bool型变量只占用一位存储空间,比int型、char型变量要小的多。
这降低了程序的空间复杂度。
三、采取的方案
本程序是将一个由8个ascii码组成的明文分组加密,生成一个由16个16进制数组成的密文。
或将一个由16个16进制数组成的密文进行脱密,生成一个由8个ascii码组成的明文。
所用密钥由16个16进制数组成。
本实验按照输入数据及初始置换、16圈迭代、子密钥生成和逆初始置换及输出数据四个步骤实现加密算法设计。
1、输入数据及初始置换
本程序首先会提示用户输入加密脱密识别码,加密输入1,脱密输入0,将此识别码存入整形变量o。
根据o的不同值,提示用户输入8个字符(加密)或16个16进制数(脱密)。
输入的明文或密文转化为二进制数后储存到布尔型数组m[65]中。
初始置换通过函数IP完成,函数输入为原始明文m,函数将输出结果保存到布尔型数组mip[65]中。
函数思想为查表,含有一个整形变量数组ip[64],保存初始变换表IP。
将mip的第i位赋值为m的第ip[i]位。
2、子密钥生成
输入16个16进制数的密钥后,将密钥保存在一个16位字符数组c中,通过ToEr函数将之变为二进制数。
ToEr函数输入为字符数组,通过switch语句逐个检查字符数组的每一位,将对应的四位二进制数存在64位布尔数组k中。
64bit密钥去掉每个字节的最高位得到56bit密钥输入,通过置换选择1变换得到
和
各28bit,通过Zhihuan_1函数实现置换选择一。
Zhihuan_1函数输入为二进制密钥数组k[64],输出为C0和D0,将C0、D0分别储存在28位布尔数组C、D中。
函数采用查表方式生成C0和D0。
根据迭代的轮数确定C和D移位循环的位数,主程序中利用一个16位整形数组来存放每一次循环左移的位数。
循环左移通过XunHuan函数实现,函数输入为循环位数和长度为28的布尔数组(C或者D),函数运行一次只能改变一个布尔数组的值。
为了减低编程复杂度,程序使用串行方法,分两次进行C、D的移位。
每完成一次C和D的移位,进行一次置换选择二。
置换选择二利用zhihuan_2函数完成。
思想和Zhihuan_1函数类似。
zhihuan_2函数输入为移位后的C、D,zhihuan_2函数将圈子密钥存放在16*48的二维布尔数组kk[17][49]中。
kk[i][48]表示第i圈的圈子密钥。
原理图如图1所示。
脱密(o=0时)需要将圈子密钥交换,此时可利用kk[0][49]充当中间变量,无需定义新的变量减少了系统开销。
图1圈子密钥生成算法
3、16圈迭代
DES的每一圈迭代采用的是Feistel模型,先将初始置换后的明文mip数组分成L和R两部分,先将R的内容放在等长的布尔数组T中,最后时需要将L的值赋为T。
之后进入F函数,F函数原理如图2。
图2F函数原理图
程序中的F函数输入有初始置换结果的右半部分R、圈子密钥kk、迭代圈数i。
输出保存在R中。
先将输入的R通过查表的方法进行E拓展,结果保存在48位布尔数组a中。
再将a与圈子密钥k按位模二加。
结果保存在a中。
接下来将a分成8组,分别进入8个S盒。
用for控制循环8次,每次操作选用6位二进制代码的开头一位和最后一位转化成十进制数,控制S盒的行数,再将6位二进制代码的中间四位转化成十进制数,控制S盒的列数。
进入第几个S盒有迭代圈数i确定。
取到S盒中的十进制数后,将它转化成二进制数,储存在32位布尔数组T中,在使用查表法完成P盒置换,最终结果保存在R中。
最后将L与R按位模二加,得到新的R,完成一次迭代。
4、逆初始置换
16次迭代后,先将L16和R16连接起来,保存到64位布尔数组m中,m之前用于保存明文,这样减小了程序占用的空间。
另外,为了保证加脱密算法的一致性,迭代时最后一圈不需要交换L与R,但程序中为了简化编程复杂度,在迭代时仍然交换了L与R。
所以在连接时需要再次交换L与R。
所以m的高32位应储存R,低32位应储存L。
逆初始置换原理同初始置换步骤,不再赘述。
四、取得的成果
利用密钥1438FBCA对明文加密,密文为6B217C871EAE79D2H结果如图3所示。
图3DES加密结果图
利用密钥1438FBCA对密文6B217C871EAE79D2脱密,明文为。
结果如图4所示。
图4DES脱密结果图
变换不同明文及密钥,均可以正常加脱密。
在报告中不再罗列。
五、心得体会
DES算法是一种分组密码算法,本人通过对一个明文分组的加脱密进行编程,耗时近一个月,独立完成了次算法的C++实现。
本人的程序不同于网上找的DES算法程序,网上的大多数程序的密文都是以ASCII码来输出的。
但是,这样输出的结果有很多乱码出现。
因为ASCII码只有在小范围内输出的结果是正常的字母、数字或者符号(从33至127),如果按ASCII输出乱码密文,脱密者就很难键入这些密文,只能通过复制粘贴进行。
而VC6.0的环境在控制台中很难进行复制操作,这样如果不借助文件,就很难完成密文的脱密。
而密文按16进制输出就不存在这个问题。
二进制串与ASCII码、16进制数之间的转化也是实验的难点之一。
C语言的课上没有讲过位运算的相关知识,本人只能通过除以二取余、查表等笨办法进行转化。
同样,密钥选用16进制也是一个道理,如果只用字符输入密钥,密钥的每八位就会局限在00100001(33)至01111111(127)范围之内,超过范围就无法用键盘进行输入密钥,这样破译者如果看到了加密程序源代码,相应的穷尽时间会减少。
通过本次编程,我发现我对C/C++语言的掌握还是不够,尤其是涉及到位运算。
我也会找机会自学这一部分内容。
六、附录
程序代码:
#include
usingnamespacestd;
voidToEr(charc[],boolk[])
{
inti,j;
j=0;
for(i=1;i<=16;i++)
{
switch(c[i])
{case'0':
k[j++]=0;
k[j++]=0;
k[j++]=0;
k[j++]=0;
break;
case'1':
k[j++]=0;
k[j++]=0;
k[j++]=0;
k[j++]=1;
break;
case'2':
k[j++]=0;
k[j++]=0;
k[j++]=1;
k[j++]=0;
break;
case'3':
k[j++]=0;
k[j++]=0;
k[j++]=1;
k[j++]=1;
break;
case'4':
k[j++]=0;
k[j++]=1;
k[j++]=0;
k[j++]=0;
break;
case'5':
k[j++]=0;
k[j++]=1;
k[j++]=0;
k[j++]=1;
break;
case'6':
k[j++]=0;
k[j++]=1;
k[j++]=1;
k[j++]=0;
break;
case'7':
k[j++]=0;
k[j++]=1;
k[j++]=1;
k[j++]=1;
break;
case'8':
k[j++]=1;
k[j++]=0;
k[j++]=0;
k[j++]=0;
break;
case'9':
k[j++]=1;
k[j++]=0;
k[j++]=0;
k[j++]=1;
break;
case'A':
k[j++]=1;
k[j++]=0;
k[j++]=1;
k[j++]=0;
break;
case'B':
k[j++]=1;
k[j++]=0;
k[j++]=1;
k[j++]=1;
break;
case'C':
k[j++]=1;
k[j++]=1;
k[j++]=0;
k[j++]=0;
break;
case'D':
k[j++]=1;
k[j++]=1;
k[j++]=0;
k[j++]=1;
break;
case'E':
k[j++]=1;
k[j++]=1;
k[j++]=1;
k[j++]=0;
break;
case'F':
k[j++]=1;
k[j++]=1;
k[j++]=1;
k[j++]=1;
break;
}
}
//for(i=0;i<64;i++)cout< //cout< } voidMtoEr(charasc[],boolm[]) { inti,j,flag,f; intas[9]; boolz[9]={0},t; for(i=1;i<=8;i++)as[i]=(int)asc[i]; for(i=1;i<=8;i++) { f=1; flag=8*(i-1); while(as[i]! =0) { z[f]=as[i]%2; as[i]/=2; f++; } //for(j=1;j<=8;j++)cout< //cout< for(j=1;j<=4;j++){t=z[j];z[j]=z[9-j];z[9-j]=t;} //z[1]=0; for(j=1;j<=8;j++)m[flag+j]=z[j]; for(j=1;j<=8;j++)z[j]=0; } //for(j=1;j<=64;j++)cout< //cout< } voidIP(boolm[],boolmip[]) { intip[64]= {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, 56,48,40,32,24,16,8,0, 58,50,42,34,26,18,10,2, 60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6}; for(inti=1;i<=64;i++)mip[i]=m[ip[i-1]+1]; } voidIP2(boolm[],boolmip[]) { intip[64]= { 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, 32,0,40,8,48,16,56,24 }; for(inti=1;i<=64;i++)mip[i]=m[ip[i-1]+1]; } voidZhihuan_1(boolk[],boolC[],boolD[]) { inta[28]= {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}; intb[28]= {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}; inti; for(i=1;i<=28;i++)C[i]=k[a[i-1]]; for(i=1;i<=28;i++)D[i]=k[b[i-1]]; //for(i=1;i<=28;i++)cout< //for(i=1;i<=28;i++)cout< } voidzhihuan_2(boolC[],boolD[],boolk[][49],intq) { inta[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}; inti; boolT[57]; for(i=1;i<=56;i++) {if(i<=28)T[i]=C[i]; elseT[i]=D[i-28]; } for(i=1;i<=48;i++) k[q+1][i]=T[a[i-1]+1]; //for(i=1;i<=48;i++)cout< } voidXunHuan(intx,boolC[]) { inti; boolT[29]; for(i=1;i<29;i++)T[i]=C[(i+x)%28+1]; for(i=1;i<29;i++)C[i]=T[i]; } voidF(boolR[],boolkk[][49],intx) { intE[48]={31,0,1,2,3,4, 3,4,5,6,7,8, 7,8,9,10,11,12, 11,12,13,14,15,16, 15,16,17,18,19,20, 19,20,21,22,23,24, 23,24,25,26,27,28, 27,28,29,30,31,0}; intS[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} } }; inti,j,p,a1,a2,k[8]; boola[49],b[33]; for(i=1;i<=48;i++)a[i]=R[E[i-1]+1]; //for(i=1;i<=48;i++)cout< for(i=1;i<=48;i++)a[i]^=kk[x][i];
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 实现 DES 算法 实验 报告