200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > DES加解密算法

DES加解密算法

时间:2018-09-29 14:40:35

相关推荐

DES加解密算法

DES算法以及其C语言实现

算法简介

DES(Data Encrytion Standard)算法,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。

DES算法属于对称加密算法,加密解密公用一套算法。

明文按64位进行分组,密钥长64位但实际上只有56位参与DES运算(第8、16、24、32、40、48、56、64位是奇偶校验位)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。

首先要生成一套加密密钥,从用户处取得一个64位长的密码口令,然后通过等分、移位、选取和迭代形成一套16个加密密钥,分别供每一轮运算中使用。

加密算法框架

DES对64 bit的明文M进行操作,M经过一个初始置换IP,置换成m0。将m0明文分成左半部分和右半部分,各32位长。然后进行16轮完全相同的运算,这些运算被称为函数f,在每一轮运算过程中数据与相应的密钥结合。

在每一轮中,密钥位移位,然后再从密钥的56位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的48位数据,再将其压缩置换成32位。这四步运算构成了函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。将该操作重复16次。

经过16轮迭代后,左,右半部分合在一起经过一个末置换(数据整理),这样就完成了加密过程。

解密过程

DES加密和解密使用相同的算法,唯一的不同是密钥的次序相反。如果各轮加密密钥分别是K1,K2,K3…K16,那么解密密钥就是K16,K15,K14…K1。

DES代码源文件

#include<stdio.h>#include<string.h>#include<stdlib.h>#include"tables.h" //数据表/*置换函数In:待置换数据指针Out:置换输出指针n:置换表长度P:置换表指针功能:将输入数据的指定位置作为输出数据的第i位。指定位置即置换表第i位的十进制数。得到的输出数据的长度即为置换表的长度。*/void myPermutation(char* In, char* Out, int n, char* P){int i = 0;for (i = 0; i < n; i++)*(Out + i) = *(In + *(P + i) - 1);*(Out + i) = '\0';}/*按位异或函数In1:二进制串1In2:二进制串2n:二进制串长度Out:异或结果功能:循环比较两个二进制串每一位,不同则为'1',相同则为'0'*/void myXOR(char* In1, char* In2, int n, char* Out){int i = 0;for (i = 0; i < n; i++)*(In1 + i) != *(In2 + i) ? *(Out + i) = '1' : *(Out + i) = '0';}/*循环左移函数In:待移位二进制串Out:移位后二进制串n:二进制串长度s:循环位数功能:将输入二进制串移位后对应位置的值赋给输出串,为保证循环(即原二进制串的第一位变成移位后的最后一位),将位次相加后与串的长度做模运算。*/void myShift(char* In, char* Out, int n, int s){int i = 0;for (i = 0; i < n; i++)*(Out + i) = *(In + (s + i) % n);*(Out + i) = '\0';}/*生成子密钥函数K:64位的密钥(*SK)[49]:得到的一轮子密钥功能:输入64位密钥,进行置换选择1,之后进行16轮操作得到16个子密钥,每一轮都将56位分成两部分,进行相应位数的移位操作,再拼接成56位进行置换选择2,得到该轮子密钥*/void mySubkey(char* K, char(*SK)[49]){char out[57], C[57], D[29], e[29], t[57];int i = 0, j = 0;myPermutation(K, out, 56, *PC_1); //置换选择1strcpy(C, out);//C0strcpy(D, out + 28); //D0for (j = 0; j < 16; j++){myShift(C, e, 28, move_time[j]); //循环左移strcpy(C, e); //CjmyShift(D, e, 28, move_time[j]);strcpy(D, e); //Djstrncpy(t, C, 28);strncpy(t + 28, D, 28);myPermutation(t, *(SK + j), 48, *PC_2);//置换选择2,得到Kj}}/*二进制转十六进制out[65]:待转换的二进制串h:二进制字符串长度*/void change(char out[65],int h){int i = 0, j = 0;char put[17];for (i = 0;i < h / 4;i++){if ((((out[i * 4] - '0') * 8 + (out[i * 4 + 1] - '0') * 4 + (out[i * 4 + 2] - '0') * 2 + (out[i * 4 + 3] - '0'))) <= 9) {put[i] = (out[i * 4] - '0') * 8 + (out[i * 4 + 1] - '0') * 4 + (out[i * 4 + 2] - '0') * 2 + (out[i * 4 + 3] - '0') + '0';}else put[i] = (out[i * 4] - '0') * 8 + (out[i * 4 + 1] - '0') * 4 + (out[i * 4 + 2] - '0') * 2 + (out[i * 4 + 3] - '0') + '7';}for (j = 0;j < h/4;j++)printf("%c", put[j]);printf("\n");}/*轮函数fL: 第t轮的32位LR: 第t轮的32位RSK: 第t轮的48位子密钥t: 轮数功能:共进行16轮操作,每轮的32位R先进行拓展置换E变成48位,再与该轮子密钥异或,然后分成8组进行S盒代换。每组通过第1,6位组成的二进制串确定S盒行号,通过第2,3,4,5位确定列号,找到对应的数并转为4位二进制串。8组代换拼接成32位为S盒代换结果,然后进行置换P。每轮经过S盒代换得到的结果与上一轮的L异或作为本轮的R,上一轮的R作为本轮的L。*/void myf(char* L, char* R, char* SK, int t){int i = 0, j = 0;int row, col;char out1[49] = {0 }, out2[49] = {0 }, out3[33] = {0 }, out4[33] = {0 }, temp[33] = {0 };printf("K%d=", t + 1);change(SK,strlen(SK));myPermutation(R, out1, 48, *E); //扩展置换Eprintf("E(R%d)=", t);change(out1,strlen(out1));myXOR(out1, SK, 48, out2);//与子密钥异或printf("E(R%d)^K%d=", t, t + 1);change(out2,strlen(out2));for (i = 0; i < 8; i++) //S盒代换{row = ((out2[i * 6] - '0') << 1) + (out2[i * 6 + 5] - '0'); //第1,6位组成行号col = ((out2[i * 6 + 1] - '0') << 3) + ((out2[i * 6 + 2] - '0') << 2) + ((out2[i * 6 + 3] - '0') << 1)+ (out2[i * 6 + 4] - '0'); //第2,3,4,5位组成列号for (j = 3; j >= 0; j--)*(out3 + (i * 4 + 3 - j)) = ((S_Box[i][row * 16 + col] >> j) & 1) + '0'; //将取到的S盒数据填到S盒输出的指定位置,先进行十进制转二进制}*(out3 + 32) = '\0';printf("%d轮S盒输出=", t + 1);change(out3,strlen(out3));myPermutation(out3, out4, 32, *P); //置换Pprintf("f(R%d,K%d)=", t, t + 1);change(out4,strlen(out4));strcpy(temp, R);//保存旧的RmyXOR(L, out4, 32, R); //更新Rprintf("R%d=", t + 1);change(R,strlen(R));strcpy(L, temp);//更新L}/*主函数功能:输入64位明文,先进行初始置换IP操作,接下来将置换输出的 64 位数据分成左右两半,左一半称为 L0 ,右一半称为 R0 ,各 32 位。然后进行16轮迭代,迭代完成后再经逆IP置换得到密文。*/int main(){char* M = "0001001000110100010101101010101111001101000100110010010100110110";char* K = "1010101010111011000010010001100000100111001101101100110011011101";char out[65], L[33], R[33], SK[16][49], cipher[65], put[17];int i = 0, j = 0;mySubkey(K, SK);//产生16轮子密钥myPermutation(M, out, 64, *IP); //初始置换IPprintf("明文:");change(M,strlen(M));printf("IP置换:");change(out,strlen(out));//printf("%d", (out[0] - '0') * 8 + (out[1] - '0') * 4 + (out[2] - '0') * 2 + (out[3] - '0'));strcpy(L, out);//L0strcpy(R, out + 32); //R0for (i = 0; i < 16; i++){printf("\n-------------------------------第%d轮------------------------------------\n", i + 1);myf(L, R, *(SK + i), i);}strncpy(out, R, 32); //L16 + R16strncpy(out + 32, L, 32);myPermutation(out, cipher, 64, *C_IP); //逆IP置换printf("\n密文:");change(cipher,strlen(cipher));return 0;}

DES表的头文件

//选择置换PC-1char PC_1[8][7] ={{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}};//选择置换PC-2char PC_2[8][6] ={{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}};//IP置换char IP[8][8] ={{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}};//逆IP置换char C_IP[8][8] ={{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}};//扩展置换Echar E[8][6] ={{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}};//扩展置换Pchar P[4][8] ={{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}};//S盒char S_Box[8][65] ={{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,10,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 move_time[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 };

参考了很多大佬的文章,简单记录下

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。