当前位置:文档之家› des课程设计

des课程设计

DES加解密算法的实现一、DES算法的概述DES(Data Encryption Standard)是由美国IBM公司于20世纪70年代中期的一个密码算(LUCIFER)发展而来,在1977年1月15日,美国国家标准局正式公布实施,并得到了ISO的认可,在过去的20多年时间里,DES被广泛应用于美国联邦和各种商业信息的保密工作中,经受住了各种密码分析和攻击,有很好的安全性。

然而,目前DES算法已经被更为安全的Rijndael算法取代,但是DES 加密算法还没有被彻底的破解掉,仍是目前使用最为普遍的对称密码算法。

所以对DES的研究还有很大价值,在国内DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键的数据保密,如信用卡持卡人的PIN码加密传输,IC卡与POS机之间的双向认证、金融交易数据包的MAC 校验等,均用到DES算法。

DES算法是一种采用传统的代替和置换操作加密的分组密码,明文以64比特为分组,密钥长度为64比特,有效密钥长度是56比特,其中加密密钥有8比特是奇偶校验,DES的加密和解密用的是同一算法,它的安全性依赖于所用的密钥。

它首先把需要加密的明文划分为每64比特的二进制的数据块,用56比特有效密钥对64比特二进制数据块进行加密,每次加密可对64比特的明文输入进行16轮的替换和移位后,输出完全不同的64比特密文数据。

由于DES算法仅使用最大为64比特的标准算法和逻辑运算,运算速度快,密钥容易产生,适合于在大多数计算机上用软件快速实现,同样也适合于在专用芯片上实现。

二、DES算法描述DES算法的加密过程首先对明文分组进行操作,需要加密的明文分组固定为64比特的块。

图2-1是DES加密算法的加密流程。

图2-2是密钥扩展处理过程。

图2-1图2-2三、DES算法的实现DES算法的加密与解密过程互逆,我们以加密算法为例,一步一步实现加密。

1、子密钥的产生由于子密钥产生与DES加密过程相互独立,所以我们先实现子密钥函数。

64比特的密钥生成16个48比特的子密钥。

其生成过程如图1-2.a. 首先我们这里64比特密码用的是16位十六进制的数转换为64比特。

b. 然后经过置换选择1.如图3-1图3-1用函数的实现方法是,首先将PC-1表存起来,然后循环每次对照表,依次取出密钥数组对应的比特。

c .接下来我们要将得到的56比特,前28位赋值给C[28];后28位赋值给D[28]。

d .接下来左右部分分别按照LS[1],循环左移,第一位移动到第28位。

每一轮移动的位数都是在上一轮移动结束的基础上再移动LS[n]位(n<17),所以第n轮移动的位数实际上为LS数组前n项的和(为方便,LS[1]代表第一轮,LS[0]=0)。

LS数组如下图3-2:图3-2e .将移动结束后的C[28],D[28]结合为K[56],按照IP2表如图3-3进行置换输出。

图3-3对应函数代码如下:// change 函数将一位16进制转换为4位2进制void change (int a,int N [4]){int i,b;i=3;while(a!=0){b=a%2;a=a/2;N [i]=b;i--;}if(i>=0)while(i>=0)N[i--]=0;}//密钥产生函数,三个参数分别表示:MW代表64位密钥,n 表示要求第几轮子密钥,key 为子密钥void KeyProd (int mw[8][8],int n,int key [48]){int a,i,h,l,j,N,tem,hm,lm,t;int d [28];int kt [56];int c [28];int k[56];int ls[17]={0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //LS数组int ip1 [8][7]={ {57,49,41,33,25,17,9}, //IP1置换表{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} } ;int pc2[48]={14,17,11,24,1,5,3,28, //IP2置换表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};i=0;for(h=0;h<8;h++) //遍历IP1表,取出来密钥表中对应的数值,依次赋值给KT[56]for(l=0;l<7;l++){ a=ip1[h][l];if(a%8==0){ hm=a/8-1;lm=7;}else{hm=a/8;lm=a%8-1;}kt[i++]=mw[hm][lm];}j=0;for(i=0;i<28;i++) //将kt[56]前28项赋值给C[28]c[j++]=kt[i];t=0;for(i=28;i<56;i++) //将kt[56]后28项赋值给D[28] d[t++]=kt[i];N=0;for(i=1;i<=n;i++) //求出第N轮左移的位数N N+=ls[i];while(N) //C[28]循环左移N位{ tem=c[0];for(i=1;i<28;i++)c[i-1]=c[i];c[27]=tem;N--;}N=0;for(i=1;i<=n;i++)N+=ls[i];while(N) ////D[28]循环左移N位{ tem=d[0];for(i=1;i<28;i++)d[i-1]=d[i];d[27]=tem;N--;}for(i=0;i<28;i++) //C[28]与D[28]合并为k[56] k[i]=c[i];for(j=0;j<28;j++)k[i++]=d[j];for(i=0;i<48;i++)//进行IP2置换key[i]=k[pc2[i]-1];}2、明文初始置换首先输入16位十六进制的数转换为64比特的明文块,按照初始置换(IP)表进行置换,DES初始置换表如图3-4所示算法实现仍通密钥函数相同遍历ip表取出明文中对应的比特。

然后将得到的64明文前32赋值给L[32]后32位赋值给R[32].图3-4初始置换表代码://输入函数void PUTIN(int mw[8][8]){char M[16];int num[4];int i,s,j,n,h,l;n=0;printf("请输入16位十六进制数:");for(i=0;i<16;i++)scanf("%c",&M[i]); for(i=0;i<16;n++,i++) {if(M[i]<60)s=M[i]-48;else if(M[i]<90)s=M[i]-55;elses=M[i]-87;change(s,num);if(4*(n+1)%8==0)h=4*(n+1)/8-1; elseh=4*(n+1)/8;if((n+1)%2==0)l=4;elsel=0;for(j=0;j<4;j++)mw[h][l++]=num[j]; }}//ipbiao函数将自动生成64位的ip置换表上下差2,左右差8 void ipbiao(int ip [8][8]){long i,j,k;for(j=0;j<4;j++){i=2+j*2;for(k=7;k>=0;k--){ip[j][k]=i;i+=8;}}for(j=4;j<8;j++){i=1+(j-4)*2;for(k=7;k>=0;k--){ip[j][k]=i;i+=8;}}}//初始置换函数将64bit 按ip表重新排列void InitRep (int mw [8][8],int tem[8][8]) {int i,j,h,l,a;int ip[8][8];ipbiao(ip); //产生ip表函数for(i=0;i<8;i++)for(j=0;j<8;j++){a=ip[i][j];if(a%8==0){ h=a/8-1;l=7;}else{h=a/8;l=a%8-1;}tem[i][j]=mw[h][l];}}//划分函数,将64位bit 分为两个32位void BreakLR (int tem [8][8] ,int L [32] ,int R [32]){int h,l,i;i=0;for (h=0;h<4;h++)for(l=0;l<8;l++)L[i++]=tem[h][l];i=0;for (h=4;h<8;h++)for(l=0;l<8;l++)R[i++]=tem[h][l];}3、轮加密DES算法的论结构分为左右两部分32比特在每一轮中被独立处理。

如图具体过程为:下一轮左半部分32比特等于上一轮右半部分32比特;而下一轮右半部分的32比特的计算则是由上一轮右半部分和轮密钥输入到F函数中进行变换,变换结果与上一轮左半部分进行异或运算,得到。

因此每一轮的变换可由公式表示:L(i)==R(i-1);R(i)=L(i-1)⊕F(R(i-1),K(i));图3-5a.扩张变换E将右半部分的32比特,进行E盒扩展,扩展成为48比特。

具体变换过程为把输入的32比特E盒扩展之后输出E[8][6]。

E[8][6]中每一位与R[32]中的对应关系如图3—6图3-6代码://扩展函数将32位变为48位首先按R[32]一条龙对E[8][6]赋值,然后再处理多出来的16位void Extension (int r[32],int E[8][6]){int i,h,l;i=0;while(i<32)for(h=0;h<8;h++)for(l=1;l<5;l++)E[h][l]=r[i++];E[0][0]=r[31];E[0][5]=r[4];i=9;for(h=1;h<7;h++){E[h][0]=r[4*h-1];E[h][5]=r[i-1];i=i+4;}E[7][0]=r[27];E[7][5]=r[0];}b 异或函数相同为假,相同为真,将E盒的输出与子密钥进行异或得到的48比特作为S盒的输入。

相关主题