DES加密算法解读.docx
《DES加密算法解读.docx》由会员分享,可在线阅读,更多相关《DES加密算法解读.docx(27页珍藏版)》请在冰豆网上搜索。
![DES加密算法解读.docx](https://file1.bdocx.com/fileroot1/2022-11/27/51599b3b-8f4b-4884-aeaf-6d5d145f8fdb/51599b3b-8f4b-4884-aeaf-6d5d145f8fdb1.gif)
DES加密算法解读
重庆交通大学
《信息安全体系》课程设计报告
班级:
姓名:
学号:
课程设计题目:
DES加密算法
所属课程:
信息安全体系
实验室(中心):
软件实验室60801
指导教师:
完成时间:
2015年12月25日
1.问题分析和任务定义
问题分析:
´DES是一种对称密码体制,它所使用的加密和解密密钥是相同的,是一种典型的按分组方式工作的密码。
´DES是一种对二进制数据(0、1)进行加密的算法,数据分组长度为64bit,密文分组长度也为64bit。
用长64位的密钥对其进行16轮代换和换位加密,最后形成密文。
´密钥有效密钥长度为56bit,8位奇偶检验位(分别为8,16,24,32,40,48,56,64位)。
´DES加密主要包括初始置换IP、16轮迭代的乘积变换、逆初始置换IP-1以及16个子密钥产生器。
任务(功能)定义:
(数据结构部分)
(1)明文转换:
publicvoidbiaoshito2mingwen(strings,int[,]a)//将明文字符串中每个字符转换为32位二进制数据,每64位二进制数据为一行.
(2)转换IP列:
publicvoidzhihuanIP_lie(int[]a,int[,]b)//将原明文字节按列写出
(3)奇偶校验:
publicvoidzhihuanIP_jiou(int[,]a)//将各列经过偶采样和奇采样
(4)行逆序:
publicvoidzhihuanIP_hangnixu(int[,]a)//将矩阵中各行元素逆序
(5)转换:
publicvoidbiaoshito2miyao8X8(strings,int[]a)//将密钥转换为64位二进制数据
(6)分组:
publicvoidsplit(int[,]a,int[,]l,int[,]r)//将8X8的数组分成两个数组,分别为8X6和8X6
(7)扩展:
publicvoidtuozhan(int[,]l1)//选择扩展运算E
(8)去掉校验位:
publicvoidqujiaoyan(int[,]a,int[,]b)
(9)得到寄存器C:
publicvoidjicunqic(int[,]a,int[]b)
(10)得到寄存器D:
publicvoidjicunqid(int[,]a,int[]b)
(11)循环左移:
publicvoidxhzyw(int[]a,intm)
(12)删除:
publicvoidshanchuc(int[]a,int[,]b);publicvoidshanchuD(int[]a,int[,]b)
(13)合并:
publicvoidhebingCD1(int[]a,int[]b,int[,]c)
(14)K按列排序:
publicvoidklie(int[,]a,int[]b,int[]c)
(15)K奇偶采样:
publicvoidkjiou(int[,]a)
(16)按K进行行逆序:
publicvoidkhangnixu(int[,]a)
2.环境简介
MicrosoftVisualStudio2010
3.程序设计
(1)DES加密过程
(2)初始IP置换
首先将输入的64bit明文,按“初始排列IP”进行移位变换,改变该64bit明文的排列顺序,然后分成两个长度分别为32bit的数据块,左边的32bit构成L0,右边的32bit构成R0。
1择扩展运算E
具体扩展方法:
令s表示E原输入数据比特的原下标,则E的输出是将原下标为s≡0或1(mod4)的各比特重复一次得到的。
②密钥加密算法
将子密钥产生器输出的48bit子密钥与扩展运算E输出的48bit按位模2相加。
③选择压缩运算S
将48bit数据自左向右分成8组,每组6bit。
而后并行送入8个S盒,每个S盒为一非线性代换网络,有6位输入,产生4位输出。
使用方法:
每个S盒输入的第一位和最后一位构成一个二进制数,转换成十进制数,用来选择相应盒子的行;中间四位对应的十进制数则选出一列。
④置换选择P
对S1至S8盒输出的32bit进行置换。
置换后的输出与左边的32bit逐位模2相加,所得到的32bit作为下一轮的输入。
(3)乘积变换
(4)子密钥的产生
(5)解密
由于DES的加密和解密使用同一算法,所以,只需要解密时把子密钥的顺序颠倒过来,即把K1~K16,换为K16~K1,再输入密文就可还原明文。
4.上机调试总结与分析
在上机调试的过程中不断发现了问题并解决了问题使程序功能实现更加合理和完善。
首先对于怎么存放转换明文,密文和密钥为二进制编码进行调试,发现,将密钥设置为8位长度,每个字符使用8位二进制表示,不足8为则用#补齐,超出8位,则只取前8位。
每个明文转化为ANSI编码,再转化为32位二进制编码。
即,每次加密,将明文以2个长度为单位分组加密。
其次,在实现加密的过程中,分为四个大步骤:
初始置换,乘积变换,子密钥生成,逆置换。
1)在初始置换中,先实现将存储的64位明文二进制分为8组,存储在8*8数组里面。
紧接着,将二维数组转置,即按列写入。
然后再将数组下标为1,3,5,7的行取出放在前面四行,0,2,4,6的行放在后四行。
然后,将每一行的数据逆序。
最后,将64位数据分为左右各32位数据,即,将前4行数据作为左边,后四行数据作为右边,分别存储在8*6的数组里面,其中每一行在存储下标为1-4的位置。
2)在乘积变换中,首先将右边的32位数据拓展,按照拓展算法将32位数据拓展为48位数据,将拓展的两列分别存储在每行下标为0和5的位置。
拓展之后,先进行字密钥生成。
生成之后,将两个8*6的数组模2相加。
再将每一行的数据送入S盒中得到一个8*4的数组。
再与之前的左边进行模2相加,得到的结果作为下一次的初始值,如此循环16次。
3)生成子密钥,首先是将64位二进制密钥按列写入8*8的数组,然后去掉最后一行,即去掉校验位。
然后再按照分组规则将剩余的56位数据分为两组28为的数据。
然后再删除两组数据中的特定值,最后再进行置换,再合并为48位子密钥。
;
4)将得到的左边和右边进行合并,合并之后,再进行逆初始置换,根据置换表进行下标更改。
在上述的操作中,首先遗忘了一点,在生成子密钥的过程中,一共生成16次,每一次需要进行循环左移位,并且左移的位数一一样。
在实现的时候忽略了这个过程,在检查的过程中找出并请修改了。
然后,进行解密算法实现。
将十六次迭代的顺序颠倒,但是最终实现不了。
发觉是因为对于循环左移位的实现有误,再次进行调整。
在调试过程中,加密和解密结果有误差,所以进行每一步的实现显示,即为整个算法的每一步实现搭建界面,通过查看具体的转换过程,进行逐步完善。
5.用户使用说明
先输入密钥、明文点“加密”按钮进行加密,将明文删除点“解密”按钮进行解密,明文框中得到解密的明文。
6.测试数据与测试结果等内容
7.总结
刚开始的对设计DES加密算法并没有清晰的了解,于是上网查找相关方面的资料,有了更深一步的了解,并开始设计自己的实验。
设计的过程充满了艰辛,感觉到设计不合理就又改,反反复复改了好久。
并在填写代码的时候还在不断改。
写代码的过程更是艰辛与困难,时间太紧迫,于是晚上熬夜写代码,修改代码,有时候修改一个代码都要几个小时,真的是很难熬,十分辛苦,但是坚持总是会有回报的,看见自己设计的东西和实验报告,心里十分开心,尽管不是很完美,但尽自己最大的努力去做事情,于心无愧。
只是有做的不好的地方,希望老师予以指导。
8.附录程序清单
///将字符或汉字转换为ANSI码
publicintbiaoshitoANSI(chars)
{
byte[]buff=System.Text.Encoding.Default.GetBytes(s.ToString());
stringq="";
for(inti=0;i{
q+=buff[i].ToString();
}
//stringtempstr=System.Text.Encoding.Default.GetString(buff);
returnint.Parse(q);
}
///将明文字符串中每个字符转换为32位二进制数据,每64位二进制数据为一行
publicvoidbiaoshito2mingwen(strings,int[,]a)
{
intsum=0;
for(inti=0;i{
intb=biaoshitoANSI(s[i]);
//stringtemp=zhuanhaun10toother(b,2,0);
stringtemp=Convert.ToString(b,2);
//MessageBox.Show(s.Length+""+temp.ToString());
if(sum==0)
{
for(intj=temp.Length-1;j>=0;j--)
{
a[i/2,31-(temp.Length-1)+j]=int.Parse(temp[j].ToString());
}
for(intk=0;k<32-temp.Length;k++)
{
a[i/2,k]=0;
}
sum=1;
}
elseif(sum==1)
{
for(intj=temp.Length-1;j>=0;j--)
{
a[i/2,63-(temp.Length-1)+j]=int.Parse(temp[j].ToString());
//MessageBox.Show(a[i/2,63-(temp.Length-1)+j].ToString());
}
for(intk=32;k<64-temp.Length;k++)
{
a[i/2,k]=0;
}
sum=0;
}
}
if(s.Length%2==1)
{
for(intk=32;k<64;k++)
{
a[(s.Length-1)/2,k]=0;
}
}
}
///将原明文字节按列写出
publicvoidzhihuanIP_lie(int[]a,int[,]b)
{
inttemp=0;
for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
b[j,i]=a[temp];
temp++;
}
}
}
///将各列经过偶采样和奇采样
publicvoidzhihuanIP_jiou(int[,]a)
{
int[,]b=newint[8,8];
for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
b[i,j]=a[i,j];
}
}
for(inti=0;i<4;i++)
{
for(intj=0;j<8;j++)
{
a[i,j]=b[2*i+1,j];
}
}
for(inti=4;i<8;i++)
{
for(intj=0;j<8;j++)
{
a[i,j]=b[2*(i-4),j];
}
}
}
///将矩阵中各行元素逆序
publicvoidzhihuanIP_hangnixu(int[,]a)
{
inttemp;
for(inti=0;i<8;i++)
{
for(intj=0;j<4;j++)
{
temp=a[i,j];
a[i,j]=a[i,7-j];
a[i,7-j]=temp;
}
}
}
///将密钥转换为64位二进制数据
publicvoidbiaoshito2miyao8X8(strings,int[]a)
{
stringss="";
for(inti=0;i{
intb=biaoshitoANSI(s[i]);
stringtemp=Convert.ToString(b,2);
intl=8-temp.Length;
for(intj=0;jtemp="0"+temp;
ss=ss+temp;
}
for(inti=0;i<8-s.Length;i++)
{
ss=ss+"00000000";
}
for(inti=0;i<64;i++)
{
a[i]=int.Parse(ss[i].ToString());
}
}
///将一维64位数组转化为二维8X8数组
publicvoidzhuanhuan64to8X8(int[]a,int[,]b)
{
intsum=0;
for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
b[i,j]=a[sum++];
}
}
}
///将8X8的数组分成两个数组,分别为8X6和8X6
///
///8X8的数组
///8X6的数组
///8X6的数组
publicvoidsplit(int[,]a,int[,]l,int[,]r)
{
int[]aa=newint[64];
intsum=0;
for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
aa[sum++]=a[i,j];
}
}
sum=0;
for(inti=0;i<8;i++)
{
for(intj=0;j<4;j++)
{
l[i,j+1]=aa[sum++];
r[i,j+1]=aa[31+sum];
}
}
}
///选择扩展运算E
publicvoidtuozhan(int[,]l1)
{
l1[0,0]=l1[7,4];
l1[1,0]=l1[0,4];
l1[2,0]=l1[1,4];
l1[3,0]=l1[2,4];
l1[4,0]=l1[3,4];
l1[5,0]=l1[4,4];
l1[6,0]=l1[5,4];
l1[7,0]=l1[6,4];
l1[0,5]=l1[1,1];
l1[1,5]=l1[2,1];
l1[2,5]=l1[3,1];
l1[3,5]=l1[4,1];
l1[4,5]=l1[5,1];
l1[5,5]=l1[6,1];
l1[6,5]=l1[7,1];
l1[7,5]=l1[0,1];
}
///去掉校验位
publicvoidqujiaoyan(int[,]a,int[,]b)
{
for(inti=0;i<7;i++)
{
for(intj=0;j<8;j++)
{
b[i,j]=a[i,j];
}
}
}
///得到寄存器c
publicvoidjicunqic(int[,]a,int[]b)
{
intsum=0;
for(inti=0;i<3;i++)
{
for(intj=7;j>=0;j--)
{
b[sum++]=a[i,j];
}
}
b[24]=a[3,7];
b[25]=a[3,6];
b[26]=a[3,5];
b[27]=a[3,4];
}
///得到寄存器d
publicvoidjicunqid(int[,]a,int[]b)
{
intsum=0;
for(inti=6;i>=4;i--)
{
for(intj=7;j>=0;j--)
{
b[sum++]=a[i,j];
}
}
b[24]=a[3,3];
b[25]=a[3,2];
b[26]=a[3,1];
b[27]=a[3,0];
}
///循环左移位
///第几轮,每轮左移位数不同
publicvoidxhzyw(int[]a,intm)
{
int[]w={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
int[]b=newint[28];
for(inti=0;i<28;i++)
b[i]=a[i];
for(inti=0;i<28;i++)
{
a[i]=b[(i+w[m])%28];
}
}
///删除寄存器C中的第9,18,22,25位
publicvoidshanchuc(int[]a,int[,]b)
{
int[]bb=newint[56];
intsum=0;
for(inti=0;i<7;i++)
{
for(intj=0;j<8;j++)
{
bb[sum++]=b[i,j];
}
}
int[]aa=newint[48]{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};
for(inti=0;i<24;i++)
{
a[i]=bb[aa[i]-1];
}
}
///删除寄存器D中的第7,10,15,26位
publicvoidshanchuD(int[]a,int[,]b)
{
int[]bb=newint[56];
intsum=0;
for(inti=0;i<7;i++)
{
for(intj=0;j<8;j++)
{
bb[sum++]=b[i,j];
}
}
int[]aa=newint[48]{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};
for(inti=24;i<48;i++)
{
a[i-24]=bb[aa[i]-1];
}
}
publicvoidhebingCD1(int[]a,int[]b,int[,]c)
{
intsum=0;
for(inti=0;i<3;i++)
{
for(intj=0;j<8;j++)
{
c[i,j]=a[sum++];
}
}
c[3,0]=a[24];
c[3,1]=a[25];
c[3,2]=a[26];
c[3,3]=a[27];
c[3,4]=b[24];
c[3,5]=b[25];
c[3,6]=b[26];
c[3,7]=b[27];
sum=4;
for(inti=4;i<7;i++)
{
for(intj=0;j<8;j++)
{
c[i,j]=b[sum++];
}
}
}
///合并寄存器C,D
publicvoidhebingCD(int[,]a,int[,]b)
{
int[]bb=newint[56];
intsum=0;
for(inti=0;i<7;i++)
{
for(intj=0;j<8;j++)
{
bb[sum++]=b[i,j];
}
}
int[]aa=newint[48]{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};
sum=0;
for(inti=0;i<8;i++)
{
for(intj=0;j<6;j++)
{
a[i,j]=bb[aa[sum++]-1];