C语言实现DES算法DES加密算法实验报告

合集下载

关于DES加密算法的C语言实现

关于DES加密算法的C语言实现

信息与网络安全实验报告计算机科学与技术学院网络工程1202班郭尚秀1208020204/********DES密码的加密过程*******************1.将字母转化为二进制数(明文&密文)分成两组完成*2.对明文m进行初始IP置换完成*3.对密钥k进行密钥置换完成*4.对密钥k进行压缩置换完成*5.对R0进行扩展变换32->48 完成*6.结果和k进行异或运算完成*7.将结果分成8组,通过8个s盒完成*8.对s盒的输出序列进行P置换完成*9.对p置换的结果与L0进行异或运算完成********************************************/#include<stdio.h>int ip[] = { //IP置换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};int jiou[] = {7,15,23,31,39,47,55,63 //进行密钥添加奇偶校验位使用};int ki[] = { //密钥置换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};int kyasuo[]= { //对密钥进行压缩置换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};int mkuozhan[]= {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};int s[8][4][16] = { //8个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, 4,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},{10, 6, 9, 0,12,11, 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}}};int p[32] = { //最后的p置换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};void main(){char mingwen1[100];int mingwen2[100];int tempmingwen[100];int L0[32],R0[32];int R48[48];char miyue1[100];int miyue2[100];int tempmiyue[100];int C0[28],D0[28];int yihuo[48]; //存放R0与K1异或的结果int sheD; //存放经过s盒之后的十进制结果int sheB[8][4]; //存放经过s盒之后的二进制结果int she[32]; //对s盒中的数据进行合并,存放经过s盒的结果int hang,lie; //存放s盒的行列序号int p2[32]; //存放经过p置换后的结果int c,d; //存放C0[0]和D0[0]int i,j; //i,j作为循环使用int icount1,icount2,k;int temp;//__________________________明文输入__________________________________________________________________________________ ________________k=0;printf("请输入明文(以'#'号结尾):\n");for(i=0; i<100; i++){scanf("%c",&mingwen1[i]);if('#' == mingwen1[i]){icount1 = i;goto loop1;}}loop1:for(i=0;i<=icount1;i++){for(j=7;j>=0;j--){temp=mingwen1[i]&(1<<j);if(0 == temp){mingwen2[k]=0;k++;}else{mingwen2[k]=1;k++;}}}//_________________________密钥输入__________________________________________________________________________________ _________________k=0;fflush(stdin); //清除缓冲区内的数据,如果不加上,则miwen[0]会多出一个LF(换行符)!!!printf("请输入密钥(以'#'号结束):\n");for(i=0; i<100; i++){scanf("%c",&miyue1[i]);if('#' == miyue1[i]){icount2 = i;goto loop2;}}loop2:for(i=0;i<=icount2;i++){for(j=7;j>=0;j--){temp=miyue1[i]&(1<<j);if(0 == temp){miyue2[k]=0;k++;}else{miyue2[k]=1;k++;}}}//**********************************************************printf("\n\nm = ");for(i=0;i<8*icount1;i++){printf("%d",mingwen2[i]);if(i== 7||i==15||i==23||i==39||i==47||i==55||i==63){printf(" ");}if(i==31){printf("\n");printf(" ");}}printf("\nk = ");for(i=0;i<8*icount2;i++){printf("%d",miyue2[i]);if(i== 7||i==15||i==23||i==39||i==47||i==55||i==63){printf(" ");}if(i==31){printf("\n");printf(" ");}}printf("\n");//**********************************************************///____________________至此二进制的明文存放在mingwen2[]中_____________________________________________________________________________//________________________进行明文的初始置换IP________________________________________________________________________________ _________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<8*icount1;i++){tempmingwen[i] = mingwen2[ip[i]-1];}//________________________置换IP后的结果存放在tempmingwen[i]中__________________________________________________________________________//________________________把明文结果存放到L0和R0中__________________________________________________________________________________ ____fflush(stdin); //清除缓冲区内的数据for(i=0;i<64;i++){if(i<32) {L0[i]=tempmingwen[i];}else {R0[i-32]=tempmingwen[i];}}//**************************************printf("\nm经过IP置换后得到:\n");printf("L0: ");for(i=0;i<32;i++){printf("%d",L0[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}printf("\nR0: ");for(i=0;i<32;i++){printf("%d",R0[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}printf("\n");//**************************************///_______________________对密文进行添加奇偶校验位__________________________________________________________________________________ _____fflush(stdin); //清除缓冲区内的数据for(i=0;i<8;i++){j=56+i;while(j>=jiou[i]){miyue2[j+1]=miyue2[j];j--;}if(i==0 || i==2 || i==4 || i==6) {miyue2[jiou[i]]=0;}else {miyue2[jiou[i]]=1;}}/**********************************************************for(i=0;i<64;i++){printf("%d",miyue2[i]);if(i== 7||i==15||i==23||i==31||i==39||i==47||i==55||i==63){printf(" ");}}**********************************************************///_________________________对密文进行密钥置换__________________________________________________________________________________ _________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<56;i++){tempmiyue[i]=miyue2[ki[i]-1];}/*********************************printf("\n\n");for(i=0;i<56;i++){printf("%d",tempmiyue[i]);if(i== 7||i==15||i==23||i==31||i==39||i==47||i==55||i==63){printf(" ");}}*********************************/fflush(stdin); //清除缓冲区内的数据for(i=0;i<56;i++){if(i<28) {C0[i]=tempmiyue[i];}else {D0[i-28]=tempmiyue[i];}}//**************************************printf("\n密钥k经过置换后得到:");printf("\nC0: ");for(i=0;i<28;i++)printf("%d",C0[i]);if(i== 7||i==15||i==23){printf(" ");}}printf("\nR0: ");for(i=0;i<28;i++){printf("%d",D0[i]);if(i== 7||i==15||i==23){printf(" ");}}printf("\n");//**************************************///_________________________分别对C0和D0进行循环左移操作__________________________________________________________________________________ __c = C0[0];d = D0[0];for(i=0;i<27;i++){C0[i] = C0[i+1];}C0[28] = c;for(i=0;i<27;i++){D0[i] = D0[i+1];}D0[28] = d;//__________________________对C0和D0进行合并存入miyue2[]中______________________________________________________________________________ fflush(stdin); //清除缓冲区内的数据for(i=0;i<56;i++){if(i<28) {miyue2[i]=C0[i];}else {miyue2[i]=D0[i-28];}}//_________________________________________________________________________________ _____-fflush(stdin); //清除缓冲区内的数据for(i=0;i<48;i++){tempmiyue[i] = miyue2[kyasuo[i]-1];}//**************************************printf("\n循环左移一位后经过密钥置换得到48位子密钥:\n");for(i=0;i<48;i++){printf("%d",tempmiyue[i]);if(i== 7||i==15||i==31||i==39||i==47){printf(" ");}if(i==23){printf("\n");}//**************************************/fflush(stdin); //清除缓冲区内的数据for(i=0;i<48;i++){R48[i]=R0[mkuozhan[i]-1];}//***************************************printf("\n\nR0经过扩展变换得到的48位序列为:\n");for(i=0;i<48;i++){printf("%d",R48[i]);if(i== 7||i==15||i==31||i==39||i==47){printf(" ");}if(i==23){printf("\n");}}//**************************************///______________________R0与K1异或______________________________________________________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<48;i++){yihuo[i] = R48[i]^tempmiyue[i];}//______________________结果存放到yihuo[]数组中_________________________________________________//***************************************printf("\n\n结果再和k1进行异或运算,得到的结果为:\n");for(i=0;i<48;i++){printf("%d",yihuo[i]);if(i== 7||i==15||i==31||i==39||i==47){printf(" ");}if(i==23){printf("\n");}}//**************************************///_______________________通过8个s盒的到32位的序列_______________________________________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<8;i++){k=0; //清除k的值hang=yihuo[(1+(i*6))-1]*2 + yihuo[(6+(i*6))-1];lie =yihuo[(2+(i*6))-1]*8 + yihuo[(3+(i*6))-1]*4 + yihuo[(4+(i*6))-1]*2 + yihuo[(5+(i*6))-1];sheD=s[i][hang][lie];for(j=3;j>=0;j--){temp=sheD&(1<<j);if(0 == temp){sheB[i][k]=0;k++;}else{sheB[i][k]=1;k++;}}}//______________________将二维数组sheB[][]中的内容转存到一维数组she中,方便以后的计算___________fflush(stdin); //清除缓冲区内的数据k=0;for(i=0;i<8;i++){for(j=0;j<4;j++){she[k]=sheB[i][j];k++;}}//*************************************printf("\n\n通过8个s盒得到32位的序列为:\n");for(i=0;i<32;i++){printf("%d",she[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}printf("\n");//*************************************///______________________对s盒的输出序列进行p置换__________________________________________________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<32;i++){p2[i]=she[p[i]-1];}//*************************************fflush(stdin); //清除缓冲区内的数据printf("\n对s盒的输出序列进行p置换,得到\n");for(i=0;i<32;i++){printf("%d",p2[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}//*************************************///______________________p置换之后和L0进行异或运算_______________________________________________________________________________fflush(stdin); //清除缓冲区内的数据for(i=0;i<32;i++){p2[i]=L0[i]^p2[i];}//______________________L0和R0交换__________________________________________________________________________________ ______________________for(i=0;i<32;i++){L0[i]=R0[i];R0[i]=p2[i];}//*************************************printf("\n\n经过以上操作,得到进过第一轮加密的结果序列为:\n");printf("L0: ");for(i=0;i<32;i++){printf("%d",L0[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}printf("\n");printf("R0: ");for(i=0;i<32;i++){printf("%d",R0[i]);if(i== 7||i==15||i==23||i==31){printf(" ");}}printf("\n");}。

DES加密算法的简单实现实验报告

DES加密算法的简单实现实验报告

DES加密算法的简单实现实验报告一、实验目的本实验的主要目的是对DES加密算法进行简单的实现,并通过实际运行案例来验证算法的正确性和可靠性。

通过该实验可以让学生进一步了解DES算法的工作原理和加密过程,并培养学生对算法实现和数据处理的能力。

二、实验原理DES(Data Encryption Standard,数据加密标准)是一种对称密钥加密算法,它是美国联邦政府采用的一种加密标准。

DES算法使用了一个共享的对称密钥(也称为密钥),用于加密和解密数据。

它采用了分组密码的方式,在进行加密和解密操作时,需要将数据分成固定长度的数据块,并使用密钥对数据进行加密和解密。

DES算法主要由四个步骤组成:初始置换(Initial Permutation),轮函数(Round Function),轮置换(Round Permutation)和最终置换(Final Permutation)。

其中初始置换和最终置换是固定的置换过程,用于改变数据的顺序和排列方式。

轮函数是DES算法的核心部分,它使用了密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。

轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。

通过多轮的迭代运算,DES算法可以通过一个给定的密钥对数据进行高强度的加密和解密操作。

三、实验步骤2.初始置换:将输入数据按照一定的规则重新排列,生成一个新的数据块。

初始置换的规则通过查表的方式给出,我们可以根据规则生成初始置换的代码。

3.轮函数:轮函数是DES算法的核心部分,它使用轮密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。

在实际的算法设计和实现中,可以使用混合逻辑电路等方式来实现轮函数。

4.轮置换:轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。

轮置换的规则也可以通过查表的方式给出。

5.最终置换:最终置换与初始置换类似,将最后一轮的结果重新排列,生成最终的加密结果。

des算法实验报告

des算法实验报告

des算法实验报告DES算法实验报告一、引言数据加密标准(Data Encryption Standard,简称DES)是一种对称密钥加密算法,由IBM公司于1975年研发并被美国国家标准局(NBS)采纳为联邦信息处理标准(FIPS)。

二、算法原理DES算法采用了分组密码的方式,将明文数据划分为固定长度的数据块(64位),并通过密钥进行加密和解密操作。

其核心是Feistel结构,每轮加密操作包括置换和替代两个步骤。

1. 置换步骤DES算法的初始置换(IP)和逆初始置换(IP-1)通过一系列的位重排操作,将输入的64位明文数据打乱,以增加加密的强度。

2. 替代步骤DES算法中使用了8个S盒(Substitution Box),每个S盒接受6位输入,并输出4位结果。

S盒的作用是将输入的6位数据映射为4位输出,通过这种非线性的映射关系,增加了算法的安全性。

3. 轮函数DES算法的加密过程包含16轮迭代,每轮迭代中都会对数据进行一系列的位重排和替代操作。

其中,轮函数是DES算法的核心部分,它通过使用子密钥对数据进行异或操作,并通过S盒替代和P盒置换操作,产生新的数据块。

三、实验步骤为了更好地理解DES算法的加密过程,我们进行了以下实验步骤:1. 输入明文和密钥我们选择了一个64位的明文数据块和一个56位的密钥作为输入。

明文数据块经过初始置换(IP)后,得到L0和R0两个32位的数据块。

2. 生成子密钥通过对密钥进行置换和循环左移操作,生成16个48位的子密钥。

3. 迭代加密对明文数据块进行16轮的迭代加密,每轮加密包括以下步骤:a. 将R(i-1)作为输入,经过扩展置换(E-box),得到48位的扩展数据。

b. 将扩展数据和子密钥Ki进行异或操作,得到48位的异或结果。

c. 将异或结果分为8个6位的数据块,分别经过8个S盒替代操作,得到32位的S盒替代结果。

d. 将S盒替代结果经过P盒置换,得到32位的轮函数输出。

des加密算法实验报告

des加密算法实验报告

DES加密算法实验报告1. 引言DES(Data Encryption Standard)是一种对称密码算法,于1977年被美国联邦信息处理标准(FIPS)确定为联邦标准。

DES加密算法采用分组密码的思想,将明文按照64位分为一组,经过一系列的置换、替代和迭代操作,最终输出加密后的密文。

本实验旨在通过对DES加密算法的实际操作,深入理解DES的工作原理和加密过程。

2. 实验步骤2.1. 密钥生成DES加密算法的核心在于密钥的生成。

密钥生成过程如下:1.将64位的初始密钥根据置换表进行置换,生成56位密钥。

2.将56位密钥分为两个28位的子密钥。

3.对两个子密钥进行循环左移操作,得到循环左移后的子密钥。

4.将两个循环左移后的子密钥合并,并根据压缩置换表生成48位的轮密钥。

2.2. 加密过程加密过程如下:1.将64位的明文按照初始置换表进行置换,得到置换后的明文。

2.将置换后的明文分为左右两部分L0和R0,每部分32位。

3.进行16轮迭代操作,每轮操作包括以下步骤:–将R(i-1)作为输入,经过扩展置换表扩展为48位。

–将扩展后的48位数据与轮密钥Ki进行异或操作。

–将异或结果按照S盒进行替代操作,得到替代后的32位数据。

–对替代后的32位数据进行置换,得到置换后的32位数据。

–将置换后的32位数据与L(i-1)进行异或操作,得到Ri。

–将R(i-1)赋值给L(i)。

4.将最后一轮迭代后得到的数据合并为64位数据。

5.对合并后的64位数据进行逆置换,得到加密后的64位密文。

3. 实验结果对于给定的明文和密钥,进行DES加密实验,得到加密后的密文如下:明文:0x0123456789ABCDEF 密钥:0x133457799BBCDFF1密文:0x85E813540F0AB4054. 结论本实验通过对DES加密算法的实际操作,深入理解了DES加密算法的工作原理和加密过程。

DES加密算法通过对明文的置换、替代和迭代操作,混淆了明文的结构,使得密文的产生与密钥相关。

【精品】DES算法实验报告

【精品】DES算法实验报告

【精品】DES算法实验报告一、理论部分DES算法是一种对称加密算法,也是目前广泛应用的加密算法之一。

DES算法使用的是分组加密的思想,将明文数据分成一定长度的数据块,按照一定的算法进行加密,得到密文数据。

DES算法中的关键是密钥,只有持有正确密钥的人才能解密。

DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要特别注意。

DES算法的加密过程包括以下几个步骤:1、密钥的生成和处理:DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要使用程序进行特殊处理,以确保生成的密钥不为弱密钥。

2、初始置换(IP):将明文数据按照一定的规则进行置换,得到置换后的数据。

3、分组:将置换后的明文数据分成左半部分和右半部分。

4、轮函数(f函数):将右半部分进行扩展置换、异或运算、S盒代替、置换等操作,得到一个新的右半部分。

5、轮秘钥生成:生成本轮加密所需要的秘钥。

6、异或运算:将左半部分和右半部分进行异或运算,得到一个新的左半部分。

7、左右交换:将左右部分进行交换。

以上步骤循环执行16次,直到得到最终的密文数据。

二、实验部分本次实验使用C语言实现了DES算法的加密和解密过程。

具体实现过程包括以下几个部分:1、密钥的生成:使用DES算法生成64位密钥,其中包括了对弱密钥的处理。

2、置换:使用DES算法中的IP置换和IP逆置换进行数据置换。

3、轮函数:使用DES算法中的f函数进行一轮加密操作。

5、加密:循环执行16轮加密操作,得到密文数据。

以上实现过程全部基于DES算法的规范。

三、结果分析1、速度慢:由于DES算法采用的是分组加密的思想,需要执行多次操作才能得到最终结果。

因此本次实验的加密和解密速度相对较慢。

2、代码简单:本次实验的代码相对简单,只需要用到一些基本数据结构和算法即可实现DES算法的加密和解密过程。

但需要注意的是,由于DES算法本身的复杂性,代码实现中需要注意细节和边界问题。

四、总结本次实验使用C语言实现了DES算法的加密和解密过程,通过实验得到了一些结果。

DES密码算法综合实验报告

DES密码算法综合实验报告
3、用C语言编程,实现DES对字符串或文件的加密和解运算,密钥为自己的名字




实验代码如下:
#include <iostream>
#include <fstream>
using namespace std;
FILE *file;
const static char rar[] = {
14, 17, 11, 24, 1, 5,
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,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25 };
bool key[16][48]={0},/*rekey[16][48],*/
char key_in[8];
void ByteToBit(bool *Out,char *In,int bits)
tmp[i*4+3]=sbox[i][(hang+1)*16+lie]%2;
tmp[i*4+2]=(sbox[i][(hang+1)*16+lie]/2)%2;
tmp[i*4+1]=(sbox[i][(hang+1)*16+lie]/4)%2;
tmp[i*4]=(sbox[i][(hang+1)*16+lie]/8)%2; }

des 加密算法实验报告

des 加密算法实验报告

des 加密算法实验报告DES加密算法实验报告一、引言数据加密标准(Data Encryption Standard,简称DES)是一种对称加密算法,由IBM公司于1975年研发并被美国联邦政府采用为标准加密算法。

DES算法具有高效、可靠、安全等特点,被广泛应用于信息安全领域。

本实验旨在通过对DES算法的实验研究,深入了解其原理、性能和应用。

二、DES算法原理DES算法采用对称密钥加密,即加密和解密使用相同的密钥。

其核心是Feistel结构,将明文分成左右两部分,经过16轮迭代加密后得到密文。

每一轮加密中,右半部分作为下一轮的左半部分,而左半部分则通过函数f和密钥进行变换。

DES算法中使用了置换、代换和异或等运算,以保证加密的安全性。

三、DES算法实验过程1. 密钥生成在DES算法中,密钥长度为64位,但实际上只有56位用于加密,8位用于奇偶校验。

实验中,我们随机生成一个64位的二进制密钥,并通过奇偶校验生成最终的56位密钥。

2. 初始置换明文经过初始置换IP,将明文的每一位按照特定规则重新排列,得到初始置换后的明文。

3. 迭代加密经过初始置换后的明文分为左右两部分,每轮加密中,右半部分作为下一轮的左半部分,而左半部分则通过函数f和子密钥进行变换。

函数f包括扩展置换、S盒代换、P盒置换和异或运算等步骤,最后与右半部分进行异或运算得到新的右半部分。

4. 逆初始置换经过16轮迭代加密后,得到的密文再经过逆初始置换,将密文的每一位按照特定规则重新排列,得到最终的加密结果。

四、DES算法性能评估1. 安全性DES算法的密钥长度较短,易受到暴力破解等攻击手段的威胁。

为了提高安全性,可以采用Triple-DES等加强版算法。

2. 效率DES算法的加密速度较快,适用于对大量数据进行加密。

但随着计算机计算能力的提高,DES算法的加密强度逐渐降低,需要采用更加安全的加密算法。

3. 应用领域DES算法在金融、电子商务、网络通信等领域得到广泛应用。

DES文件加密实验报告

DES文件加密实验报告

DES文件加密实验报告一、DES算法简介DES是Data Encryption Standard(数据加密标准)的缩写。

它是由IBM公司研制的一种加密算法,美国国家标准局于1977年公布把它作为非机要部门使用的数据加密标准,二十年来,它一直活跃在国际保密通信的舞台上,扮演了十分重要的角色。

DES是一个分组加密算法,他以64位为分组对数据加密。

同时DES也是一个对称算法:加密和解密用的是同一个算法。

它的密匙长度是56位(因为每个第8 位都用作奇偶校验),密匙可以是任意的56位的数,而且可以任意时候改变。

其中有极少量的数被认为是弱密匙,但是很容易避开他们。

所以保密性依赖于密钥。

二、用C#实现DES文件加密指定文件,输入密钥来加密和解密数据。

DESCryptoServiceProvider基于对称加密算法。

Symmetricencryption 需要一个密钥和一个初始化向量(IV) 加密请。

要解密的数据,必须具有相同的密钥和IV。

使用的加密提供程序来获取encryptingobject (CreateEncryptor) 创建CryptoStream类的一个实例,现有输出文件流对象的构造函数的一部分。

要解密文件,执行以下步骤:创建一个方法,并命名该按钮DecryptFile.解密过程是类似于theencryption 进程,但是,DecryptFile过程从EncryptFile过程的两个主要区别。

而不是CreateEncryptor使用CreateDecryptor来创建CryptoStream对象,用于指定如何使用该对象。

解密的文本写入目标文件,CryptoStream对象是现在而不是目标流的来源。

三、运行环境可将DES文件加解密软件的可执行.exe文件直接在xp,win7等系统上运行。

四、实验结果1、开始界面2、打开要加密文件、输入密钥3、加密4、打开要解密文件、输入密钥5、解密五、主要算法代码public static void EncryptFile(string sInputFilename, string sOutputFilename, string sKey){FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);DESCryptoServiceProvider DES = new DESCryptoServiceProvider();DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);ICryptoTransform desencrypt = DES.CreateEncryptor();CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);byte[] bytearrayinput = new byte[fsInput.Length];fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Close();fsInput.Close();fsEncrypted.Close();}public static void DecryptFile(string sInputFilename, string sOutputFilename, string sKey){try{DESCryptoServiceProvider DES = new DESCryptoServiceProvider();DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);ICryptoTransform desdecrypt = DES.CreateDecryptor();CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read);StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);fsDecrypted.Write(new StreamReader(cryptostreamDecr,Encoding.GetEncoding("GB2312")).ReadToEnd());fsDecrypted.Flush();fsDecrypted.Close();}catch (Exception e){MessageBox.Show(e.Message);}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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中。

64 bit密钥去掉每个字节的最高位得到56 bit密钥输入,通过置换选择1变换得到0C和0D各28 bit,通过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]充当中间变量,无需定义新的变量减少了系统开销。

1216图1 圈子密钥生成算法3、16圈迭代DES的每一圈迭代采用的是Feistel模型,先将初始置换后的明文mip数组分成L 和R两部分,先将R的内容放在等长的布尔数组T中,最后时需要将L的值赋为T。

之后进入F函数,F函数原理如图2。

图2 F函数原理图程序中的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。

逆初始置换原理同初始置换步骤,不再赘述。

四、取得的成果利用密钥201601211438FBCA对明文81623317加密,密文为6B217C871EAE79D2H结果如图3所示。

图3 DES加密结果图利用密钥201601211438FBCA对密文6B217C871EAE79D2脱密,明文为81623317。

结果如图4所示。

图4 DES脱密结果图变换不同明文及密钥,均可以正常加脱密。

在报告中不再罗列。

五、心得体会DES算法是一种分组密码算法,本人通过对一个明文分组的加脱密进行编程,耗时近一个月,独立完成了次算法的C++实现。

本人的程序不同于网上找的DES算法程序,网上的大多数程序的密文都是以ASCII码来输出的。

但是,这样输出的结果有很多乱码出现。

因为ASCII码只有在小范围内输出的结果是正常的字母、数字或者符号(从33至127),如果按ASCII输出乱码密文,脱密者就很难键入这些密文,只能通过复制粘贴进行。

而VC,这样如果不借助文件,就很难完成密文的脱密。

而密文按16进制输出就不存在这个问题。

二进制串与ASCII码、16进制数之间的转化也是实验的难点之一。

C语言的课上没有讲过位运算的相关知识,本人只能通过除以二取余、查表等笨办法进行转化。

同样,密钥选用16进制也是一个道理,如果只用字符输入密钥,密钥的每八位就会局限在00100001(33)至01111111(127)范围之内,超过范围就无法用键盘进行输入密钥,这样破译者如果看到了加密程序源代码,相应的穷尽时间会减少。

通过本次编程,我发现我对C/C++语言的掌握还是不够,尤其是涉及到位运算。

我也会找机会自学这一部分内容。

六、附录程序代码:#include <iostream>using namespace std;void ToEr(char c[],bool k[]){int i,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;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;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;break;case 'F':k[j++]=1;k[j++]=1;k[j++]=1;k[j++]=1;break;}}// for (i=0;i<64;i++) cout<<k[i];// cout<<endl;}void MtoEr(char asc[],bool m[]){int i,j,flag,f;int as[9];bool z[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;f++;}// for(j=1;j<=8;j++) cout<<z[j];// cout<<endl;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<<m[j];// cout<<endl;}void IP(bool m[],bool mip[]){int ip[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 (int i=1;i<=64;i++) mip[i]=m[ip[i-1]+1];}void IP2(bool m[],bool mip[]){int ip[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 (int i=1;i<=64;i++) mip[i]=m[ip[i-1]+1]; }void Zhihuan_1(bool k[],bool C[],bool D[]){int a[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};int b[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};int i;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<<C[i]; cout<<endl;// for(i=1;i<=28;i++) cout<<D[i]; cout<<endl;}void zhihuan_2(bool C[],bool D[],bool k[][49],int q) {int a[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};int i;bool T[57];for (i=1;i<=56;i++){if(i<=28) T[i] = C[i];else T[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<<k[q+1][i]; cout<<endl; }void XunHuan(int x,bool C[]){int i;bool T[29];for(i=1;i<29;i++) T[i] = C[(i+x)%28+1];for(i=1;i<29;i++) C[i] = T[i];}void F(bool R[],bool kk[][49],int x){int E[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};int S[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}}};int i,j,p,a1,a2,k[8];bool a[49],b[33];for (i=1;i<=48;i++) a[i] = R[E[i-1]+1];// for (i=1;i<=48;i++) cout<<a[i];for (i=1;i<=48;i++) a[i]^= kk[x][i];// for (i=1;i<=48;i++) cout<<a[i];p=1;for (i=0;i<8;i++){a1 = a[p]*2+a[p+5];//左右两位换成十进制数a2 = a[p+1]*8+a[p+2]*4+a[p+3]*2+a[p+4]; //中间4位换成十进制数// cout<<a1<<endl;// cout<<a2<<endl;p += 6;k[i] = S[i][a1][a2];// cout<<k[i]<<endl;}p=1;for (i=0;i<8;i++){switch (k[i]){case 0: b[p++] = 0;b[p++] = 0;b[p++] = 0;b[p++] = 0;break;case 1: b[p++] = 0;b[p++] = 0;b[p++] = 0;b[p++] = 1;break;case 2: b[p++] = 0;b[p++] = 0;b[p++] = 1;b[p++] = 0;break;case 3: b[p++] = 0;b[p++] = 0;b[p++] = 1;b[p++] = 1;break;case 4: b[p++] = 0;b[p++] = 1;b[p++] = 0;b[p++] = 0;break;case 5: b[p++] = 0;b[p++] = 1;b[p++] = 0;b[p++] = 1;break;case 6: b[p++] = 0;b[p++] = 1;b[p++] = 1;b[p++] = 0;break; case 7: b[p++] = 0;b[p++] = 1;b[p++] = 1;b[p++] = 1;break; case 8: b[p++] = 1;b[p++] = 0;b[p++] = 0;b[p++] = 0;break; case 9: b[p++] = 1;b[p++] = 0;b[p++] = 0;b[p++] = 1;break; case 10: b[p++] = 1;b[p++] = 0;b[p++] = 1;b[p++] = 0;break; case 11: b[p++] = 1;b[p++] = 0;b[p++] = 1;b[p++] = 1;break; case 12: b[p++] = 1;b[p++] = 1;b[p++] = 0;b[p++] = 0;break; case 13: b[p++] = 1;b[p++] = 1;b[p++] = 0;b[p++] = 1;break; case 14: b[p++] = 1;b[p++] = 1;b[p++] = 1;b[p++] = 0;break;case 15: b[p++] = 1;b[p++] = 1;b[p++] = 1;b[p++] = 1;break;}}bool T[33];for(i=1;i<=32;i++) T[i]=b[i];int P[32]={15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};for(i=1;i<=32;i++) R[i]=T[P[i-1]+1];}void main(){ char c[17],asc[9];int i,j,mout[17];bool k[65],kk[17][49],C[29],D[29],m[65],mip[65],L[33],R[33],T[33]; //k存放二进制密钥,kk存放16圈的圈子密钥,m存放明文,mip存放明文初始变换后int z[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};int o; //C、D存放圈子密钥生产算法的左右两个部分。

相关文档
最新文档