有关DES的加密流程详解des算法加密流程_lkw23333的博客-CSDN博客_des密钥加密过程
此处只做简略介绍,或者看代码注释
简要流程
(1)输入8位字符明文以及设定8位字符的加密密钥;
(2)将字符串的明文转换为64位的二进制表示;密钥也转换为64位二进制表示;
(3)对64位的密钥进行密钥扩展生16个48位的子密钥;
(4)对64位明文进行ip置换,分成L与R两组各32位;
(5)R经过轮函数F后与L进行异或操作生成新的R,新的L由之前的R代替;
(6)重复上述步骤16次后再进行一次IP逆置换即可得到64位密文;
(7)将加密后64位密文转为16位16进制输出方便显示;
(8)解密与加密步骤相同只是部分操作相反;
总结
整个des算法涉及到的那种晦涩的理论知识并不多所以理解起来很容易。各种操作通过代码实现起来都很ez,理解起来也很ez。就是过程稍微有点繁杂,而且在写代码的过程中不能调试,只能写完了调,这就导致找bug有点痛苦。不过这个过程是有收获的。
#include#include int IP_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 }; // IP-1置换表 int IPR_Table[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 }; // E扩展表 int E_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, 1 }; // PC1置换表 int PC1_Table[56]={ 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 }; // pc2表 int PC2_Table[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 }; // 移位表 int LOOP_Table[16]={ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; // S盒 int S_Box[8][4][16]={ //S1 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, //S2 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, //S3 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, //S4 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, //S5 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, //S6 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, 10,15, 4, 2, 7,12, 0, 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, //S7 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, 13, 0,11, 7, 4, 0, 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, //S8 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 }; //P置换表 int P_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 }; //执行des加密 void doDes(int *mingBit, char *ciphertext, int *keyBit); //拷贝数组 void bitCopy(int *input, int *output, int length); //做ip置换和逆置换 void doIp(int *array, int length, int *table); //异或运算 void doXor(int *output, int *input, int length); //E盒扩展 void doE(int *R, int *eTemp, int length); //S盒压缩 void doS(int *R, int *eTemp); //P盒置换 void doP(int *array); //两个PC表的置换 void doPc_1(int *keyBit, int *output); void doPc_2(int *iKey, int *C, int *D); //循环左移动 void lMove(int *C, int *D, int moveBit); //子密钥生成 void setIkey(int *keyBit, int iKey[16][48]); //轮函数F void lunF(int *R, int *iKey); //字符转位 void charToBit(char *input , int *output, int length); //位转字符 void bitToChar(int *input, char *output, int length); //des解密函数 void deDes(char *mingWen,char *ciphertext, char *keyBit); //ip置换根据table确定 void doIp(int *array, int length, int *table){ int temp[64] = {0}; bitCopy(array, temp, 64); for(int i = 0; i < length; ++i){ array[i] = temp[table[i] - 1]; } } //整个程序的异或运算执行函数 void doXor(int *output, int *input, int length){ for(int i=0; i 48,方便后面与子密钥异或 void doE(int *R, int *eTemp, int length) { for(int i = 0; i < length; ++i){ eTemp[i] = R[E_Table[i] - 1]; } } //S盒压缩 48——>32 void doS(int *R, int *eTemp) { int i, x, y; //注意指针的移动步数 for(i = 0; i < 8; ++i, eTemp += 6, R += 4){ x = eTemp[0]*2 + eTemp[5]; y = eTemp[1]*8 + eTemp[2]*4 + eTemp[3]*2 + eTemp[4]; // printf("%d %dn", x, y); char T = (char)S_Box[i][x][y]; charToBit(&T, R, 4); } } //简单的P盒置换 void doP(int *array) { int temp[32] = {0}; bitCopy(array, temp, 32); for(int i = 0; i < 32; ++i){ array[i] = temp[P_Table[i] - 1]; } } //密钥的pc_1表置换,剔除奇偶校验位 void doPc_1(int *keyBit, int *output){ for(int i = 0; i < 56; ++i){ output[i] = keyBit[PC1_Table[i] - 1]; } } //合并c,d两部分进行pc_2的置换 56——>48 void doPc_2(int *iKey, int *C, int *D){ int temp[56]={0}; bitCopy(C, temp, 28); bitCopy(D, temp+28, 28); for(int i=0; i<48; ++i){ iKey[i] = temp[PC2_Table[i]-1]; } } //密钥循环左移 void lMove(int *C, int *D, int moveBit){ int temp[28] = {0}; bitCopy(C, temp, 28); bitCopy(temp+moveBit, C, 28-moveBit); bitCopy(temp, C+28-moveBit, moveBit); bitCopy(D, temp, 28); bitCopy(temp+moveBit, D, 28-moveBit); bitCopy(temp, D+28-moveBit, moveBit); } //生成子密钥 void setIkey(int *keyBit, int iKey[16][48]) { int temp[56]={0}; int C[28]; int D[28]; doPc_1(keyBit, temp);//先做pc1剔除校验位,在拆成两组 bitCopy(temp, C, 28); bitCopy(temp+28, D, 28); for(int i=0; i<16; ++i){ lMove(C, D, LOOP_Table[i]); doPc_2(iKey[i], C, D); } } void lunF(int *R, int *iKey) { int eTemp[48]={0}; //E盒扩展 doE(R, eTemp, 48); //和密钥异或 doXor(eTemp, iKey, 48); //S盒压缩 doS(R, eTemp); //P盒压缩 doP(R); } //字符转换为位方便加密 void charToBit(char *input , int *output, int length) { int i=0; for(i=0;i < length;i++) { output[i]=(input[i/8]>>(i%8))&1; } } //位转字符,复原 void bitToChar(int *input, char *output, int length) { int i; for(i=0;i<(length/8);i++) { output[i]=0; } for(i=0;i =0;i--) { bitCopy(L, temp, 32); lunF(L, iKey[i]); doXor(R, L, 32); bitCopy(R, L, 32); bitCopy(temp, R, 32); } doIp(cBit, 64, IPR_Table); printf("n"); bitToChar(cBit, mingWen, 64); } void bitToHex(char *output, int *input, int length) { int i; for(i=0;i 9) { output[i]=output[i]%16+'7'; } else output[i]=output[i]%16+'0'; } } void hexToBit(int *output, char *input,int length) { int i; for(i=0;i >(i%4))&0x01; } else { output[i]=((input[i/4]-'7')>>(i%4))&0x01; } } } int main(){ int mingBit[64] = {0}; char ciphertext[16]; int keyBit[64] = {0}; char mingWen[8]="lkw23333"; char key[8]="ssssssss"; char deKey[8]; printf("明文为:n"); for(int i = 0; i < 8; ++i) { printf("%c", mingWen[i]); } printf("n"); charToBit(mingWen, mingBit, 64); charToBit(key, keyBit, 64); doDes(mingBit, ciphertext, keyBit); printf("加密后:n"); for(int i = 0; i < 16; ++i) { printf("%c", ciphertext[i]); } printf("n"); printf("请输入密钥解密:"); gets(deKey); charToBit(deKey, keyBit, 64); deDes(mingWen, ciphertext, keyBit); printf("明文为:n"); for(int i = 0; i < 8; ++i) { printf("%c", mingWen[i]); } printf("n"); return 0; }



