利用C语言实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:
1.在加密过程16轮迭代过程中,最后一轮迭代运算后的结果并没有进行交换,即C=IP-1(R16,L16),这样做的目的是为了加密解密使用同一个算法
2.在S盒的过程中,移位后应该加括号,否则+的优先级高于<<,会出错,下面是算法源码:
1 #include "des.h" 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 const unsigned char IP_table[64] = { 6 58, 50, 42, 34, 26, 18, 10, 2, 7 60, 52, 44, 36, 28, 20, 12, 4, 8 62, 54, 46, 38, 30, 22, 14, 6, 9 64, 56, 48, 40, 32, 24, 16, 8, 10 57, 49, 41, 33, 25, 17, 9, 1, 11 59, 51, 43, 35, 27, 19, 11, 3, 12 61, 53, 45, 37, 29, 21, 13, 5, 13 63, 55, 47, 39, 31, 23, 15, 7 14 }; 15 16 const unsigned char IPR_table[64] = { 17 40, 8, 48, 16, 56, 24, 64, 32, 18 39, 7, 47, 15, 55, 23, 63, 31, 19 38, 6, 46, 14, 54, 22, 62, 30, 20 37, 5, 45, 13, 53, 21, 61, 29, 21 36, 4, 44, 12, 52, 20, 60, 28, 22 35, 3, 43, 11, 51, 19, 59, 27, 23 34, 2, 42, 10, 50, 18, 58, 26, 24 33, 1, 41, 9, 49, 17, 57, 25 25 }; 26 27 const unsigned char E_table[48] = { 28 32, 1, 2, 3, 4, 5, 29 4, 5, 6, 7, 8, 9, 30 8, 9, 10, 11, 12, 13, 31 12, 13, 14, 15, 16, 17, 32 16, 17, 18, 19, 20, 21, 33 20, 21, 22, 23, 24, 25, 34 24, 25, 26, 27, 28, 29, 35 28, 29, 30, 31, 32, 1 36 }; 37 38 const unsigned char P_table[32] = { 39 16, 7, 20, 21, 29, 12, 28, 17, 40 1, 15, 23, 26, 5, 18, 31, 10, 41 2, 8, 24, 14, 32, 27, 3, 9, 42 19, 13, 30, 6, 22, 11, 4, 25 43 }; 44 45 const unsigned char PC1_table[56] = { 46 57, 49, 41, 33, 25, 17, 9, 47 1, 58, 50, 42, 34, 26, 18, 48 10, 2, 59, 51, 43, 35, 27, 49 19, 11, 3, 60, 52, 44, 36, 50 63, 55, 47, 39, 31, 23, 15, 51 7, 62, 54, 46, 38, 30, 22, 52 14, 6, 61, 53, 45, 37, 29, 53 21, 13, 5, 28, 20, 12, 4 54 }; 55 56 const unsigned char LOOP_table[16] = { 57 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 58 }; 59 60 const unsigned char PC2_table[48] = { 61 14, 17, 11, 24, 1, 5, 62 3, 28, 15, 6, 21, 10, 63 23, 19, 12, 4, 26, 8, 64 16, 7, 27, 20, 13, 2, 65 41, 52, 31, 37, 47, 55, 66 30, 40, 51, 45, 33, 48, 67 44, 49, 39, 56, 34, 53, 68 46, 42, 50, 36, 29, 32 69 }; 70 71 const unsigned char sbox[8][4][16] = { 72 // S1 73 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 74 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 75 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 76 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 77 //S2 78 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 79 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 80 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 81 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 82 //S3 83 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 84 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 85 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 86 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 87 //S4 88 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 89 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 90 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 91 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 92 //S5 93 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 94 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 95 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 96 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 97 //S6 98 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 99 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 100 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 101 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 102 //S7 103 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 104 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 105 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 106 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 107 //S8 108 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 109 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 110 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 111 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 112 }; 113 114 void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){ 115 for(int i=0;i<bits;i++) 116 out[i]=(in[i/8]>>(7-i%8))&1; 117 } 118 119 void BitToByte(unsigned char* out, const unsigned char* in, const int bits){ 120 memset(out, 0, (bits + 7) / 8); 121 for(int i=0;i<bits;i++) 122 out[i/8]|=in[i]<<(7-i%8); 123 } 124 125 void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){ 126 unsigned char tmp[64] = {0}; 127 for (int i = 0; i < len; i++) 128 tmp[i] = in[table[i] - 1]; 129 memcpy(out, tmp, len); 130 } 131 132 void RotateL(unsigned char* in, const int len, int loop){ 133 static unsigned char tmp[64]; 134 memcpy(tmp, in, len); 135 memcpy(in, in + loop, len - loop); 136 memcpy(in + len - loop, tmp, loop); 137 } 138 139 static unsigned char subKey[16][48] = { 0 }; 140 void setKey(const unsigned char* in){ 141 char key[64] = { 0 }; 142 ByteToBit(key, in, 64); 143 char temp[56]={0}; 144 Transform(temp, key, PC1_table, 56); 145 for(int i=0;i<16;i++){ 146 RotateL(temp, 28, LOOP_table[i]); 147 RotateL(temp + 28, 28, LOOP_table[i]); 148 Transform(subKey[i], temp, PC2_table, 48); 149 } 150 } 151 152 void xor(unsigned char* in1,const unsigned char* in2,int len){ 153 for(int i=0;i<len;i++) 154 in1[i]^=in2[i]; 155 } 156 157 void sbox_exchange(unsigned char* out,const unsigned char* in){ 158 char row, column; 159 for (int i = 0; i < 8; i++){ 160 char num = 0; 161 row = (in[6 * i]<<1)+ in[6 * i + 5]; 162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4]; 163 num = sbox[i][row][column]; 164 for (int j = 0; j < 4; j++) 165 { 166 out[4 * i + j] = (num >> (3 - j)) & 1; 167 } 168 } 169 } 170 171 void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){ 172 unsigned char temp[48]={0}; 173 unsigned char res[32]={0}; 174 Transform(temp, in, E_table, 48); 175 xor(temp,subKey,48); 176 sbox_exchange(res,temp); 177 Transform(out, res, P_table, 32); 178 } 179 180 void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 181 unsigned char input[64] = { 0 }; 182 unsigned char output[64] = { 0 }; 183 unsigned char tmp[64] = { 0 }; 184 ByteToBit(input, in, 64); 185 Transform(tmp, input, IP_table, 64); 186 char* Li = &tmp[0], *Ri = &tmp[32]; 187 setKey(key); 188 for(int i=0;i<16;i++){ 189 char temp[32]={0}; 190 memcpy(temp,Ri,32); 191 F_func(Ri, Ri,subKey[i]); 192 xor(Ri, Li, 32); 193 memcpy(Li,temp,32); 194 } 195 RotateL(tmp, 64, 32);//the input is LR,output is RL 196 Transform(output, tmp, IPR_table, 64); 197 BitToByte(out, output,64); 198 } 199 200 void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 201 unsigned char input[64] = { 0 }; 202 unsigned char output[64] = { 0 }; 203 unsigned char tmp[64] = { 0 }; 204 ByteToBit(input, in, 64); 205 Transform(tmp, input, IP_table, 64); 206 char* Li = &tmp[0], *Ri = &tmp[32]; 207 setKey(key); 208 RotateL(tmp, 64, 32); 209 for (int i = 0; i < 16; i++){ 210 char temp[32] = { 0 }; 211 memcpy(temp, Li, 32); 212 F_func(Li, Li,subKey[15 - i]); 213 xor(Li, Ri, 32); 214 memcpy(Ri, temp, 32); 215 } 216 Transform(output, tmp, IPR_table, 64); 217 BitToByte(out, output, 64); 218 }