版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件实现流程图节点1节点1加密过程64位明文进行IP置换后进行分组Li[32]与Ri[32];i=0Ri[32]进行E扩展,生成48位比特串。48位比特串与子密钥keys[i+1]进行异或运算。得到的48位比特串分为8组,进入8个S盒中,并按照S盒的规则输出8个十进制数将8个十进制数转换为32位比特串。节点132位比特串进行P置换,产生新的32位比特串32位比特串与Li[32]进行异或,产生R(i+1)[32]L(i+1)[32]=Ri[32];i++R16[32]在前,L16[32]在后进行合并,合并后进行IP逆置换,即产生密文i>15NY结束开始输入密文和密钥密文和密钥转换成二进制,存储在文件中读出64位密文和密钥64位密钥进行pc-1置换,生成56位C[i+1]与D[i+1]合并为56位比特串,并进行pc-2置换,产生子密钥keys[i+1],i++;C[i]与D[i]左移一位或者两位,由左移表决定左移位数Ls[16].左移产生C[i+1]与D[i+1]56位比特串分成左右各28位。C[i]与D[i],i=0;i>15NY节点1节点1加密过程64位明文进行IP置换后进行分组Li[32]与Ri[32];i=0Ri[32]进行E扩展,生成48位比特串。48位比特串与子密钥keys[i+1]进行异或运算。得到的48位比特串分为8组,进入8个S盒中,并按照S盒的规则输出8个十进制数将8个十进制数转换为32位比特串。节点132位比特串进行P置换,产生新的32位比特串32位比特串与Li[32]进行异或,产生R(i+1)[32]L(i+1)[32]=Ri[32];i++R16[32]在前,L16[32]在后进行合并,合并后进行IP逆置换,即产生密文i>15NY结束开始输入密文和密钥密文和密钥转换成二进制,存储在文件中读出64位密文和密钥64位密钥进行pc-1置换,生成56位C[i+1]与D[i+1]合并为56位比特串,并进行pc-2置换,产生子密钥keys[i+1],i++;C[i]与D[i]左移一位或者两位,由左移表决定左移位数Ls[16].左移产生C[i+1]与D[i+1]56位比特串分成左右各28位。C[i]与D[i],i=0;i>15NY二、标准DES的加密过程1、明文与密钥的输入 首先8位ACSII字符的明文与密钥的输入,存放在mingwen[8]和miyao[8]中,然后将这些8位的ASCII字符转换成二进制的64位的明文和密钥,分别存放在mingwenB[64]和miyaoB[64]中,并将二进制的明文和密钥放在文件中 intstr[8],i,j,ch,k; FILE*fp4;fp4=fopen("明文二进制.txt","w"); k=0; for(i=0;i<8;i++) { ch=mingwen[i]; for(j=0;j<8;j++) { str[j]=ch%2; ch=ch/2; } for(j=7;j>=0;j--) { mingwenB[k]=str[j]; k++; fprintf(fp4,"%d",str[j]); } } 密钥的转换和存储同理。2、密钥的产生 1)、64位miyaoB[64]经过pc-1置换,生成56位的比特串。定义pc1_Table[56],存放在afterpc1[56]中。 for(i=0;i<56;i++)afterpc1[i]=miyaoB[pc1_Table[i]-1]; 2)、56位比特串分组,生成C0[28]和D0[28] for(i=0;i<28;i++)C0[i]=afterpc1[i]; for(j=0,i=28;i<56;i++,j++)D0[j]=afterpc1[i]; 3)、C0[28]、D0[28]进行左移,产生C[16][28]和D[16][28],为进行pc-2置换产生密钥做准备。 for(i=0;i<27;i++) //第一轮数据生成C[0][28]与D[0][28] { C[0][i]=C0[i+1]; D[0][i]=D0[i+1]; } C[0][27]=C0[0]; D[0][27]=D0[0]; for(i=1;i<16;i++) //第二轮数据至第十六轮数据生成 { if(i==1||i==8||i==15) { for(j=0;j<27;j++) //左移1位 { C[i][j]=C[i-1][j+1]; D[i][j]=D[i-1][j+1]; } C[i][27]=C[i-1][0]; D[i][27]=D[i-1][0]; } else //左移2位 { for(j=0;j<26;j++) { C[i][j]=C[i-1][j+2]; D[i][j]=D[i-1][j+2]; } C[i][26]=C[i-1][0]; C[i][27]=C[i-1][1]; D[i][26]=D[i-1][0]; D[i][27]=D[i-1][1]; } } //产生16轮左右数据,为pc-2置换准备。 4)、左右两部分比特串合并,存放在intbeforekey[16][56]中 k=0; for(i=0;i<16;i++) { for(j=0;j<28;j++) beforekey[i][j]=C[i][j]; for(k=0;k<28;k++,j++) beforekey[i][j]=D[i][k]; } 5)、beforekey[16][56]经过pc-2置换,产生16轮密钥keys[16][48], for(i=0;i<16;i++) for(j=0;j<48;j++) keys[i][j]=beforekey[i][pc_2table[j]-1];至此,16轮子密钥产生完毕,为keys[16][48]。3、密文的产生 1)、明文经过初始置换IP置换。结果放在afterIP[64]中。 for(j=0;j<64;j++) { afterIP[j]=mingwenB[IP_table[j]-1]; } 2)、明文的第0次分组,左部分L0[32],右部分R0[32]。 for(i=0;i<32;i++) L0[i]=afterIP[i]; for(j=0,i=32;i<64;i++,j++) R0[j]=afterIP[i]; 3)、为产生密文,要进行16轮的循环,每次循环生成一个L[i][32]和R[i][32],下面进行第一次循环,生成L[0][32]和R[0][32]。 for(i=0;i<32;i++) //Li=R(i-1) L[0][i]=R0[i]; 4)、至于R[0][32]的生成,R[0][32]=L0[32]^f(R0,keys[0])。因此,要首先计算出f值。R0[32]经过E变换,由32位扩展为48位,然后与子密钥进行异或,为进入S盒做准备。结果放在afterER0[48]中 for(i=0;i<48;i++) afterER0[i]=R0[E_table[i]-1]; 5)、E扩展后,与子密钥进行异或,生成进入S盒前的数据。存放在beforeS[48]. for(i=0;i<48;i++) if(afterER0[i]==keys[0][i]) beforeS[i]=0; else beforeS[i]=1; 6)、要进入S盒的48位比特串要经过8个不同的S盒,因此,将48位比特串分在8个数组中,放在beforeSBox[8][6]. for(k=0,i=0;i<8;i++) for(j=0;j<6;j++) { beforeSBox[i][j]=beforeS[k]; k++; } 7)、进入S盒后,进过8个S盒,每个S盒产生一个十进制的数字,在0~15之间。beforeSBox[i][6]中的6个数字,第0、5位组成了S盒的行号,第1、2、3、4,4位组成了S盒的列号,根据行列选中S盒中的数据作为输出,存放在afterSBox[8]中。 inthang,lie; for(i=0;i<8;i++) { hang=beforeSBox[i][0]*2+beforeSBox[i][5]; lie=beforeSBox[i][1]*8+beforeSBox[i][2]*4+beforeSBox[i][3]*2+beforeSBox[i][4]; afterSBox[i]=SBox[i][hang][lie]; } 8)、由S盒出来的8个十进制数字转换成32位的二进制比特串,存放在beroreP[32]中,为接下来的P置换做准备。 k=0; inttemp; intstr1[4]; for(i=0;i<8;i++) { temp=afterSBox[i]; for(j=0;j<4;j++) { str1[j]=temp%2; temp=temp/2; } for(j=3;j>=0;j--) { beforep[k]=str1[j]; k++; } } 9)、转换为二进制的32位比特串进行P置换,生成新的32位比特串,也就是f的值。存放在P[32]中。 for(i=0;i<32;i++) p[i]=beforep[p_table[i]-1]; 至此,第一轮的循环已经完成,成功产生了L[0][32]和R[0][32]。 10)、对于剩下的15轮循环,用一个循环语句进行控制,生成余下的15轮中间数据的左部和右部,最后产生L[15][32]和R[15][32]。 11)、得到的最后一轮左部32位比特串和右部32位比特串进行合并,但是,合并的时候,右部32位比特串在前,R[15][32]在前,而L[15][32]在后。结果存放在beforeoutput[64]中 for(i=0;i<32;i++) //数据合并,R[15][32]在前,L[15][32]在后面 beforeoutput[i]=R[15][i]; for(i=32,j=0;i<64;i++,j++) beforeoutput[i]=L[15][j]; 12)、左右数据合并后的比特串进行最后的逆置换,生成64位的二进制密文。存放在output[64]中。 for(i=0;i<64;i++) output[i]=beforeoutput[IPR_tabel[i]-1];//得到64位密文 13)、将得到的64位密文转换为8位的ASCII字符。 intcharB[8][8]; k=0;charmiwen[8]; for(i=0;i<8;i++) for(j=0;j<8;j++) { charB[i][j]=output[k]; k++; } for(i=0;i<8;i++) { str[i]=0; if(charB[i][0]==1) str[i]=str[i]+128; if(charB[i][1]==1) str[i]=str[i]+64; if(charB[i][2]==1) str[i]=str[i]+32; if(charB[i][3]==1) str[i]=str[i]+16; if(charB[i][4]==1) str[i]=str[i]+8; if(charB[i][5]==1) str[i]=str[i]+4; if(charB[i][6]==1) str[i]=str[i]+2; if(charB[i][7]==1) str[i]=str[i]+1; } m_outputMiwen=""; for(i=0;i<8;i++) miwen[i]=str[i]; //至此,得到密文miwen[8]三、标准DES的解密过程 解密与加密的过程几乎完全相同,唯一不同的地方是:在进行E扩展后要与子密钥进行异或的时候,第一轮要与第十六轮子密钥进行异或。依次类推,第十六轮要与第一轮子密钥进行异或。因此对于DES的解密过程就不再细说。程序运行结果截图1、初始界面,界面的初始化输入的明文/密文是“20082374”2、点击加密:进入加密界面,在这个界面里显示加密过程中的所有细节,包括循环的次数,每轮循环的子密钥、左右部数据。3、再次点击加密按钮,进行数据的加密,64位的明文经过加密生成64位密文,“64位明文:”是输入的8位明文的二进制表示。“64位密钥:”是输入的8位密钥的二进制表示。“64位密文:”是经过加密之后产生的密文。“循环轮数”是记录十六轮循环的次数。“子密钥”记录每次循环的时候与R(i-1)进行异或的48位子密钥。“左部(Li)”指的是每次循环生成的Li,左部32位比特串。“右部(Ri)”指的是每次循环产生的右部Ri,32位比特串。4、点击返回按钮,返回主界面。5、点击解密按钮,进入解密界面,在这个界面里显示了解密过程中的所有细节,包括循环的次数,每轮循环的子密钥、左右部数据。6、点击解密按钮,进行数据的加密,64位的密文经过解密生成64位的明文,“64位密文:”是输入的8位密文的二进制表示。“64位密钥:”是输入的8位密钥的二进制表示。“64位明文:”是经过解密之后产生的明文。“循环轮数”是记录十六轮循环的次数。“子密钥”记录每次循环的时候与R(i-1)进行异或的48位子密钥。“左部(Li)”指的是每次循环生成的Li,左部32位比特串。“右部(Ri)”指的是每次循环产生的右部Ri,32位比特串。7、点击返回按钮,返回主界面8、点击退出按钮,退出程序,程序结束。
密文对密钥敏感性的测试 在明文不变的情况下,通过对密钥改变一位和多位进行密文对密钥敏感性的测试,观察密文的改变情况。下面给出部分数据和分析结果。 例:明文:20082374密钥:1:abcdefgh,2:bbcdefgh3:abddefgh4:accdefgh5:abcdefgi6:abcdefgg7:abcdefhg8:abcdeffh9:abcdefhh10:abcdeggh11:abcdeegh这下密钥均是相对于密钥“abcdefgh”改变一位,得到的密文如下:01:111000110000100111010000101110000010110101101011000111010011110102:011010010111110010001101001110100010111001000011110001010001111003:000101100101110010100010001001110110111111100000111100001100000104:111000110000100111010000101110000010110101101011000111010011110105:111000110000100111010000101110000010110101101011000111010011110106:101001100100000010111000111001101110001001101111001010010111110107:111101010001101010110101111000110101000101110000101000111100111008:111000110000100111010000101110000010110101101011000111010011110109:111110001010010100010010100110100001011101100111111111010001010010:111000110000100111010000101110000010110101101011000111010011110111:1001010000011100101100000100111000110010011111010000010001101111 通过对类似的一百组数据进行比较和分析,密钥改变一位,密文改变的位数分别有28位、34位、34位、39位、0位、27位、31位、33位、25位、24位等等。通过一系列的测试,对密钥改变一位,密文的位数改变范围为0~34,密钥改变一位而密文不改变的概率几乎为零,改变位数在20位以上的占95%以上。下面对密钥改变两位测试, 例:明文20082374密钥:1:abcdefgh,2:bacdefgh3:abdcefgh4:abcdefhg5:abcdffgh6:abccdfgh7:abbdefhh8:abbdefgg9:acddefgh10:abcddegh11:abcceegh密文:01:111000110000100111010000101110000010110101101011000111010011110102:011010010111110010001101001110100010111001000011110001010001111003:000010101101010011010101100011000001001000011001101010001010100004:111101010001101010110101111000110101000101110000101000111100111005:010100010101100010001011001011100111101010010011010010010110011106:101110100011011110101110010011011100110101000011010101110001111007:111110001010010100010010100110100001011101100111111111010001010008:101001100100000010111000111001101110001001101111001010010111110109:000101100101110010100010001001110110111111100000111100001100000110:100101000001110010110000010011100011001001111101000001000110111101:111000110000100111010000101110000010110101101011000111010011110111:0001100011010010000011000110101101011111001100010100110001001001 通过对类似数据进行比较分析,对密钥改变2位,密文的位数变化情况为:26位、35位、35位、33位、32位、25位、25位、39位、30位、38位等。对密钥改变两位,密文的位数改变范围为大致为:25~39位。分析结果:标准DES加密算法密文对密钥十分敏感,密文改变一位或者几位,都会是相应的密文改变二十几位,大部分情况下密文位数的改变在半数以上,也就是改变的位数超过32位。由于标准DES加密算法对于密钥十分敏感,所以使用这种算法加密的安全性取决于密钥,密钥的复杂程度和密钥的安全性决定了加密的数据的安全性。编程体会 通过这次课程设计,用程序实现了标准DES加密与解密算法。谈到编程体会与收获,最主要的一个收获就是对DES算法的深入理解和掌握。由于要编写代码实现DES算法,因此对于DES算法的每一个细节可以说是了如指掌了,每一个步骤总是推敲了一遍又一遍,找到最为简洁而清晰的实现方法。例如,在编写的过程中,我参考了一些网上的代码,那些代码在DES的十六轮加密与解密循环的实现上,竟然硬生生每一次循环写一次代码,为每一次循环中出现的变量定义了十六次,虽然思路清晰,确使得程序变得异常的庞大,增大很大的内存开销,使得程序执行的效率就不高。我在处理解密与解密的循环时,由于,第一次循环使用的数据是第一次分组的数据,与之后的数据在形式上相同,但表达上却不相同,因此,对于加密与解密的十六轮循环,我单独处理第一次循环,然后利用统一的表达方式和变量进行余下的十五轮循环,第十五轮循环结束的时候,就产生了用于产生密文或明文的最后的左部和右部数据。 通过这次课程设计,另外一个收获就是提高了自己编程能力,在编程实现DES算法的时候,需要进行大量的代码编写工作,这使得我编写代码的能力有了大大的提高,差错纠错的能力也相应的得到了提高。 最后是感谢和老师的教诲。
核心源代码1、加密过程(JiaMi.cpp)//JiaMi.cpp:implementationfile//#include"stdafx.h"#include"DES.h"#include"JiaMi.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif#include"DESDlg.h"///////////////////////////////////////////////////////////////////////////////JiaMidialogJiaMi::JiaMi(CWnd*pParent/*=NULL*/) :CDialog(JiaMi::IDD,pParent){ //{{AFX_DATA_INIT(JiaMi) m_Mingwen=_T(""); m_Miyao=_T(""); m_Miwen=_T(""); m_outputMiwen=_T(""); //}}AFX_DATA_INIT}voidJiaMi::DoDataExchange(CDataExchange*pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(JiaMi) DDX_Control(pDX,IDC_LIST1,m_output); DDX_Text(pDX,IDC_Mingwen,m_Mingwen); DDX_Text(pDX,IDC_Miyao,m_Miyao); DDX_Text(pDX,IDC_Miwen,m_Miwen); DDX_Text(pDX,IDC_outMiwen,m_outputMiwen); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(JiaMi,CDialog) //{{AFX_MSG_MAP(JiaMi) ON_BN_CLICKED(IDC_back,Onback) ON_BN_CLICKED(IDC_JiaMi,OnJiaMi) //}}AFX_MSG_MAPEND_MESSAGE_MAP()//JiaMimessagehandlersBOOLJiaMi::OnInitDialog(){ CDialog::OnInitDialog(); m_output.ModifyStyle(0,LVS_REPORT); DWORDstyle=m_output.GetExStyle(); style=style^LVS_EX_CHECKBOXES; m_output.SetExtendedStyle(style|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); m_output.InsertColumn(0,"循环轮数",LVCFMT_LEFT,80); m_output.InsertColumn(1,"子密钥",LVCFMT_LEFT,450); m_output.InsertColumn(2,"左部(Li)",LVCFMT_LEFT,350); m_output.InsertColumn(3,"右部(Ri)",LVCFMT_LEFT,350); //TODO:Addextrainitializationhere returnTRUE;//returnTRUEunlessyousetthefocustoacontrol //EXCEPTION:OCXPropertyPagesshouldreturnFALSE}voidJiaMi::Onback(){ //TODO:Addyourcontrolnotificationhandlercodehere ShowWindow(SW_HIDE); CDESDlgdlg; dlg.DoModal();}voidJiaMi::OnJiaMi(){ //TODO:Addyourcontrolnotificationhandlercodehere /*64位明文的输入:将明文和密钥转换成二进制并显示*/ FILE*fp1,*fp2; inti,j,k; intstr[8]; charmingwen[8],miyao[8]; //存储从文件中读取的明文和密钥 intmingwenB[64],miyaoB[64]; //存储64位二进制的明文和密钥 fp1=fopen("data.txt","r"); fp2=fopen("miyao.txt","r"); if(fp1==NULL||fp2==NULL) { MessageBox("明文和密钥文件打开失败!"); return; } for(i=0;i<8;i++) { fscanf(fp1,"%c",&mingwen[i]); fscanf(fp2,"%c",&miyao[i]); } fclose(fp1); fclose(fp2); FILE*fp4,*fp5; charch; fp4=fopen("明文二进制.txt","w"); fp5=fopen("密钥二进制.txt","w"); k=0; for(i=0;i<8;i++) { ch=mingwen[i]; for(j=0;j<8;j++) { str[j]=ch%2; ch=ch/2; } for(j=7;j>=0;j--) { mingwenB[k]=str[j]; k++; fprintf(fp4,"%d",str[j]); } } fclose(fp4); k=0; for(i=0;i<8;i++) { ch=miyao[i]; for(j=0;j<8;j++) { str[j]=ch%2; ch=ch/2; } for(j=7;j>=0;j--) { miyaoB[k]=str[j]; k++; fprintf(fp5,"%d",str[j]); } } fclose(fp5); m_Mingwen=""; for(i=0;i<64;i++) //二进制明文显示在界面上 { m_Mingwen=m_Mingwen+(char)(48+mingwenB[i]); if((i+1)%8==0) m_Mingwen=m_Mingwen+""; } m_Miyao=""; for(i=0;i<64;i++) //二进制密钥显示在界面上 { m_Miyao=m_Miyao+(char)(48+miyaoB[i]); if((i+1)%8==0) m_Miyao=m_Miyao+""; } /*初始置换IP*/ intIP_table[64]={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}; intafterIP[64]; for(j=0;j<64;j++) { afterIP[j]=mingwenB[IP_table[j]-1]; } /*明文的第零次分组,L0[32],R0[32]*/ intL0[32],R0[32]; for(i=0;i<32;i++) L0[i]=afterIP[i]; for(j=0,i=32;i<64;i++,j++) R0[j]=afterIP[i]; /*十六轮子密钥的生成*/ intpc_1table[56]={ //pc_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}; intpc_2table[48]={ //pc_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}; intafterpc_1[56]; /*经过pc_1置换*/ for(i=0;i<56;i++) afterpc_1[i]=miyaoB[pc_1table[i]-1]; /*密钥第0次分组*/ intC0[28],D0[28]; for(i=0;i<28;i++) C0[i]=afterpc_1[i]; for(j=0,i=28;i<56;i++,j++) D0[j]=afterpc_1[i]; /*十六轮子密钥产生前的中间数据,左移产生的C[16][28],D[16][28]*/ intC[16][28],D[16][28]; for(i=0;i<27;i++) //第一轮数据生成C[0][28]与D[0][28] { C[0][i]=C0[i+1]; D[0][i]=D0[i+1]; } C[0][27]=C0[0]; D[0][27]=D0[0]; for(i=1;i<16;i++) //第二轮数据至第十六轮数据生成 { if(i==1||i==8||i==15) { for(j=0;j<27;j++) //左移1位 { C[i][j]=C[i-1][j+1]; D[i][j]=D[i-1][j+1]; } C[i][27]=C[i-1][0]; D[i][27]=D[i-1][0]; } else { for(j=0;j<26;j++) { C[i][j]=C[i-1][j+2]; D[i][j]=D[i-1][j+2]; } C[i][26]=C[i-1][0]; C[i][27]=C[i-1][1]; D[i][26]=D[i-1][0]; D[i][27]=D[i-1][1]; } } /*十六轮子密钥初始数据合并,为pc_2置换生成子密钥做准备*/ intbeforekey[16][56]; k=0; for(i=0;i<16;i++) { for(j=0;j<28;j++) beforekey[i][j]=C[i][j]; for(k=0;k<28;k++,j++) beforekey[i][j]=D[i][k]; }/*beforekey[16][56]经过pc_2置换,生成16轮子密钥key[16][48]*/ intkeys[16][48]; for(i=0;i<16;i++) for(j=0;j<48;j++) keys[i][j]=beforekey[i][pc_2table[j]-1];/*十六轮循环生成密文,首先是L[16][32]和R[16][32]的生成*/ intL[16][32],R[16][32]; intE_table[48]={ 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,31}; intafterER0[48],beforeS[48]; for(i=0;i<32;i++) //Li=R(i-1) L[0][i]=R0[i]; for(i=0;i<48;i++) //E置换,生成48位数据,与子密钥进行异或,为进入S盒做准备 afterER0[i]=R0[E_table[i]-1]; for(i=0;i<48;i++) if(afterER0[i]==keys[0][i]) beforeS[i]=0; else beforeS[i]=1;/*将beforeS[48]分在8个数组中,为经过8个S盒准备*/ intbeforeSBox[8][6]; k=0; for(i=0;i<8;i++) for(j=0;j<6;j++) { beforeSBox[i][j]=beforeS[k]; k++; }/*S盒变换,48位数据生成32位数据*/ intafterSBox[8]; intSBox[8][4][16]={ //S盒变换表 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}; inthang,lie; for(i=0;i<8;i++) { hang=beforeSBox[i][0]*2+beforeSBox[i][5]; lie=beforeSBox[i][1]*8+beforeSBox[i][2]*4+beforeSBox[i][3]*2+beforeSBox[i][4]; afterSBox[i]=SBox[i][hang][lie]; }/*将从S盒中出来的8个十进制数字转换成32位的二进制数*/ intbeforep[32]; k=0; inttemp; intstr1[4]; for(i=0;i<8;i++) { temp=afterSBox[i]; for(j=0;j<4;j++) { str1[j]=temp%2; temp=temp/2; } for(j=3;j>=0;j--) { beforep[k]=str1[j]; k++; } }/*从S盒输入的32位的二进制数进行P置换,生成的即是f函数的结果*/ intp_table[32]={ 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}; intp[32]; for(i=0;i<32;i++) p[i]=beforep[p_table[i]-1];/*p[32]与L0[32]进行异或,得到R[0][32]*/ for(i=0;i<32;i++) { R[0][i]=p[i]+L0[i]; if(R[0][i]==2) R[0][i]=0; }/*已经生成L[0][32]和R[0][32],下面进行十五轮循环,生成其余L[i][32]和R[i][32]*/ intafterER[16][48]; intn; for(i=1;i<16;i++) { for(j=0;j<32;j++) L[i][j]=R[i-1][j]; for(j=0;j<48;j++) //E置换 afterER[i][j]=R[i-1][E_table[j]-1]; for(j=0;j<48;j++) //与子密钥进行异或 { if(afterER[i][j]==keys[i][j]) beforeS[j]=0; else beforeS[j]=1; } k=0; for(j=0;j<8;j++) //生成进入S盒钱的8个数组,分别进入8个S盒 for(n=0;n<6;n++) { beforeSBox[j][n]=beforeS[k]; k++; } for(j=0;j<8;j++) //进入S盒,从8个S盒中生成8个数 { hang=beforeSBox[j][0]*2+beforeSBox[j][5]; lie=beforeSBox[j][1]*8+beforeSBox[j][2]*4+beforeSBox[j][3]*2+beforeSBox[j][4]; afterSBox[j]=SBox[j][hang][lie]; } k=0; for(j=0;j<8;j++) //S盒出来的8个十进制数转换成32位的二进制数 { temp=afterSBox[j]; for(n=0;n<4;n++) { str1[n]=temp%2; temp=temp/2; } for(n=3;n>=0;n--) { beforep[k]=str1[n]; k++; } } for(j=0;j<32;j++) p[j]=beforep[p_table[j]-1]; for(j=0;j<32;j++) if(p[j]==L[i-1][j]) R[i][j]=0; else R[i][j]=1; }/*通过十五轮循环,最后得到L[15][32]和R[15][32],合并之后进行IP逆置换生成密文*/ intbeforeoutput[64]; intoutput[64]; intIPR_tabel[64]={ 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}; for(i=0;i<32;i++) //数据合并,R[15][32]在前,L[15][32]在后面 beforeoutput[i]=R[15][i]; for(i=32,j=0;i<64;i++,j++) beforeoutput[i]=L[15][j]; for(i=0;i<64;i++) output[i]=beforeoutput[IPR_tabel[i]-1];//得到64位密文 m_Miwen=""; for(i=0;i<64;i++) //将64位二进制密文输出到界面上 { m_Miwen=m_Miwen+(char)(48+output[i]); if((i+1)%8==0) m_Miwen=m_Miwen+""; }/*将output[64]二进制密文转换成ASCII字符*/ intcharB[8][8]; k=0; for(i=0;i<8;i++) for(j=0;j<8;j++) { charB[i][j]=output[k]; k++; } charmiwen[8]; for(i=0;i<8;i++) { str[i]=0; if(charB[i][0]==1) str[i]=str[i]+128; if(charB[i][1]==1) str[i]=str[i]+64; if(charB[i][2]==1) str[i]=str[i]+32; if(charB[i][3]==1) str[i]=str[i]+16; if(charB[i][4]==1) str[i]=str[i]+8; if(charB[i][5]==1) str[i]=str[i]+4; if(charB[i][6]==1) str[i]=str[i]+2; if(charB[i][7]==1) str[i]=str[i]+1; } m_outputMiwen=""; for(i=0;i<8;i++) miwen[i]=str[i]; //至此,得到密文miwen[8] miwen[i]='\0'; m_outputMiwen=miwen; CStringtemp1,temp2,temp3; char*ch1,*ch2,*ch3; for(i=0;i<16;i++) { intm=m_output.InsertItem(0,""); charchtempL[40]="\0",chtempkey[55]="\0",chtempR[40]="\0",number[4]="\0"; intctempL[32],ctempkey[48],ctempR[32]; for(j=0;j<32;j++) { ctempL[j]=L[i][j]; ctempR[j]=R[i][j]; } for(j=0;j<48;j++) ctempkey[j]=keys[i][j]; for(j=0;j<32;j++) { temp1.Format("%d",ctempL[j]); ch1=temp1.GetBuffer(temp1.GetLength()); strcat(chtempL,ch1); if((j+1)%8==0) strcat(chtempL,""); temp2.Format("%d",ctempR[j]); ch2=temp2.GetBuffer(temp2.GetLength()); strcat(chtempR,ch2); if((j+1)%8==0) strcat(chtempR,""); } for(j=0;j<48;j++) { temp3.Format("%d",ctempkey[j]); ch3=temp3.GetBuffer(temp3.GetLength()); strcat(chtempkey,ch3); if((j+1)%8==0) strcat(chtempkey,""); } _itoa(i+1,number,10); m_output.SetItemText(m,0,number); m_output.SetItemText(m,1,chtempkey); m_output.SetItemText(m,2,chtempL); m_output.SetItemText(m,3,chtempR); } UpdateData(false);}2、解密过程(JieMi.cpp)//JieMi.cpp:implementationfile#include"stdafx.h"#include"DES.h"#include"JieMi.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif#include"DESDlg.h"//JieMidialogJieMi::JieMi(CWnd*pParent/*=NULL*/) :CDialog(JieMi::IDD,pParent){ //{{AFX_DATA_INIT(JieMi) m_Mingwen=_T(""); m_Miwen=_T(""); m_Miyao=_T(""); m_outputMingwen=_T(""); //}}AFX_DATA_INIT}voidJieMi::DoDataExchange(CDataExchange*pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(JieMi) DDX_Control(pDX,IDC_LIST1,m_output); DDX_Text(pDX,IDC_Mingwen,m_Mingwen); DDX_Text(pDX,IDC_Miwen,m_Miwen); DDX_Text(pDX,IDC_Miyao,m_Miyao); DDX_Text(pDX,IDC_outMingwen,m_outputMingwen); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(JieMi,CDialog) //{{AFX_MSG_MAP(JieMi) ON_BN_CLICKED(IDC_back,Onback) ON_BN_CLICKED(IDC_JieMi,OnJieMi) //}}AFX_MSG_MAPEND_MESSAGE_MAP()//JieMimessagehandlersBOOLJieMi::OnInitDialog(){ CDialog::OnInitDialog(); m_output.ModifyStyle(0,LVS_REPORT); DWORDstyle=m_output.GetExStyle(); style=style^LVS_EX_CHECKBOXES; m_output.SetExtendedStyle(style|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); m_output.InsertColumn(0,"循环轮数",LVCFMT_LEFT,80); m_output.InsertColumn(1,"子密钥",LVCFMT_LEFT,450); m_output.InsertColumn(2,"左部(Li)",LVCFMT_LEFT,350); m_output.InsertColumn(3,"右部(Ri)",LVCFMT_LEFT,350); //TODO:Addextrainitializationhere returnTRUE;//returnTRUEunlessyousetthefocustoacontrol //EXCEPTION:OCXPropertyPagesshouldreturnFALSE}voidJieMi::Onback(){ //TODO:Addyourcontrolnotificationhandlercodehere ShowWindow(SW_HIDE); CDESDlgdlg; dlg.DoModal();}voidJieMi::OnJieMi(){ //TODO:Addyourcontrolnotificationhandlercodehere FILE*fp1,*fp2; inti,j,k; intstr[8]; charmiwen[8],miyao[8]; //存储从文件中读取的明文和密钥 intmiwenB[64],miyaoB[64]; //存储64位二进制的明文和密钥 fp1=fopen("data.txt","r"); fp2=fopen("miyao.txt","r"); if(fp1==NULL||fp2==NULL) { MessageBox("明文和密钥文件打开失败!"); return; } for(i=0;i<8;i++) { fscanf(fp1,"%c",&miwen[i]); fscanf(fp2,"%c",&miyao[i]); } fclose(fp1); fclose(fp2); FILE*fp4,*fp5; charch; fp4=fopen("密文二进制.txt","w"); fp5=fopen("密钥二进制.txt","w"); k=0; for(i=0;i<8;i++) { ch=miwen[i]; for(j=0;j<8;j++) { str[j]=ch%2; ch=ch/2; } for(j=7;j>=0;j--) { miwenB[k]=str[j]; k++; fprintf(fp4,"%d",str[j]); } } fclose(fp4); k=0; for(i=0;i<8;i++) { ch=miyao[i]; for(j=0;j<8;j++) { str[j]=ch%2; ch=ch/2; } for(j=7;j>=0;j--) { miyaoB[k]=str[j]; k++; fprintf(fp5,"%d",str[j]); } } fclose(fp5); charMiwentemp[75]="\0",Miyaotemp[75]="\0"; CStringtemp1; char*cha; for(i=0;i<64;i++) { temp1.Format("%d",miwenB[i]); cha=temp1.GetBuffer(temp1.GetLength()); strcat(Miwentemp,cha); if((i+1)%8==0) strcat(Miwentemp,""); } m_Miwen=Miwentemp; //二进制密文显示在界面上 for(i=0;i<64;i++) { temp1.Format("%d",miyaoB[i]); cha=temp1.GetBuffer(temp1.GetLength()); strcat(Miyaotemp,cha); if((i+1)%8==0) strcat(Miyaotemp,""); } m_Miyao=Miyaotemp; //二进制密钥显示在界面上/*密钥的生成*/ intpc_1table[56]={ //pc_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}; intpc_2table[48]={ //pc_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}; intafterpc_1[56];/*经过pc_1置换*/ for(i=0;i<56;i++) afterpc_1[i]=miyaoB[pc_1table[i]-1]; /*密钥第0次分组*/ intC0[28],D0[28]; for(i=0;i<28;i++) C0[i]=afterpc_1[i]; for(j=0,i=28;i<56;i++,j++) D0[j]=afterpc_1[i];/*十六轮子密钥产生前的中间数据,左移产生的C[16][28],D[16][28]*/ intC[16][28],D[16][28]; for(i=0;i<27;i++) //第一轮数据生成C[0][28]与D[0][28] { C[0][i]=C0[i+1]; D[0][i]=D0[i+1]; } C[0][27]=C0[0]; D[0][27]=D0[0]; for(i=1;i<16;i++) //第二轮数据至第十六轮数据生成 { if(i==1||i==8||i==15) { for(j=0;j<27;j++) //左移1位 { C[i][j]=C[i-1][j+1]; D[i][j]=D[i-1][j+1]; } C[i][27]=C[i-1][0]; D[i][27]=D[i-1][0]; } else //左移2位 { for(j=0;j<26;j++) { C[i][j]=C[i-1][j+2]; D[i][j]=D[i-1][j+2]; } C[i][26]=C[i-1][0]; C[i][27]=C[i-1][1]; D[i][26]=D[i-1][0]; D[i][27]=D[i-1][1]; } } /*十六轮子密钥初始数据合并,为pc_2置换生成子密钥做准备*/ intbeforekey[16][56]; k=0; for(i=0;i<16;i++) { for(j=0;j<28;j++) beforekey[i][j]=C[i][j]; for(k=0;k<28;k++,j++) beforekey[i][j]=D[i][k]; }/*beforekey[16][56]经过pc_2置换,生成16轮子密钥key[16][48]*/ intkeys[16][48]; for(i=0;i<16;i++) for(j=0;j<48;j++) keys[i][j]=beforekey[i][pc_2table[j]-1];/*初始置换IP*/ intIP_table[64]={ 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}; intafterIP[64]; for(i=0;i<64;i++) { afterIP[i]=miwenB[IP_table[i]-1]; } /*明文的第零次分组,L0[32],R0[32]*/ intL0[32],R0[32]; for(i=0;i<32;i++) L0[i]=afterIP[i]; for(j=0,i=32;i<64;i++,j++) R0[j]=afterIP[i]; /*十六轮循环生成密文,首先是L[16][32]和R[16][32]的生成*/ intL[16][32],R[16][32]; intE_table[48]={ 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,31}; intafterER0[48],beforeS[48]; for(i=0;i<32;i++) //Li=R(i-1) L[0][i]=R0[i]; for(i=0;i<48;i++) //E置换,生成48位数据,与第十五轮子密钥进行异或,为进入S盒做准备 afterER0[i]=R0[E_table[i]-1]; for(i=0;i<48;i++) if(afterER0[i]==keys[15][i]) beforeS[i]=0; else beforeS[i]=1;/*将beforeS[48]分在8个数组中,为经过8个S盒准备*/ intbeforeSBox[8][6]; k=0; for(i=0;i<8;i++) for(j=0;j<6;j++) { beforeSBox[i][j]=beforeS[k]; k++; }/*S盒变换,48位数据生成32位数据*/ intafterSBox[8]; intSBox[8][4][16]={ //S盒变换表 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}; inthang,lie; for(i=0;i<8;i++) {
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 童话故事里的勇气与智慧12篇
- 四年级语文课程教学设计方案
- 拎包入住型门店招聘管理方案
- 变电站建筑给排水施工详细方案
- 中小学防溺水安全教育活动方案
- 房地产开发项目职业卫生风险管控方案
- 光伏电站运维计划方案
- 海上码头施工方案
- 土建施工方案编制参考范本
- 水井工程专项方案
- 神经内科品管圈成果汇报-提高脑卒中偏瘫患者早期自我肢体功能锻炼规范执行率
- 缺血性脑卒中静脉溶栓护理
- 电子电路基础-电子科技大学中国大学mooc课后章节答案期末考试题库2023年
- 四年级科学上册期末试卷及答案-苏教版
- DB51T 2875-2022彩灯(自贡)工艺灯规范
- 小学数学人教版六年级上册全册电子教案
- 主要负责人重大危险源安全检查表
- 《工程经济学》模拟试题答案 东北财经大学2023年春
- 2023-2024学年广西壮族自治区来宾市小学数学五年级下册期末自测试卷
- 2023年福海县政务中心综合窗口人员招聘笔试模拟试题及答案解析
- GB/T 25129-2010制冷用空气冷却器
评论
0/150
提交评论