1 #include "DES.h"
2
3 //IP置换表
4 int IP[] = {
5 58, 50, 42, 34, 26, 18, 10, 2,
6 60, 52, 44, 36, 28, 20, 12, 4,
7 62, 54, 46, 38, 30, 22, 14, 6,
8 64, 56, 48, 40, 32, 24, 16, 8,
9 57, 49, 41, 33, 25, 17, 9, 1,
10 59, 51, 43, 35, 27, 19, 11, 3,
11 61, 53, 45, 37, 29, 21, 13, 5,
12 63, 55, 47, 39, 31, 23, 15, 7 };
13
14 //IP-1置换表
15 int IP_1[] = {
16 40, 8, 48, 16, 56, 24, 64, 32,
17 39, 7, 47, 15, 55, 23, 63, 31,
18 38, 6, 46, 14, 54, 22, 62, 30,
19 37, 5, 45, 13, 53, 21, 61, 29,
20 36, 4, 44, 12, 52, 20, 60, 28,
21 35, 3, 43, 11, 51, 19, 59, 27,
22 34, 2, 42, 10, 50, 18, 58, 26,
23 33, 1, 41, 9, 49, 17, 57, 25 };
24
25 //将64位密钥变成56位
26 int PC_1[] = {
27 57, 49, 41, 33, 25, 17, 9,
28 1, 58, 50, 42, 34, 26, 18,
29 10, 2, 59, 51, 43, 35, 27,
30 19, 11, 3, 60, 52, 44, 36,
31 63, 55, 47, 39, 31, 23, 15,
32 7, 62, 54, 46, 38, 30, 22,
33 14, 6, 61, 53, 45, 37, 29,
34 21, 13, 5, 28, 20, 12, 4 };
35
36 //将56位密钥压缩成48位子密钥
37 int PC_2[] = {
38 14, 17, 11, 24, 1, 5,
39 3, 28, 15, 6, 21, 10,
40 23, 19, 12, 4, 26, 8,
41 16, 7, 27, 20, 13, 2,
42 41, 52, 31, 37, 47, 55,
43 30, 40, 51, 45, 33, 48,
44 44, 49, 39, 56, 34, 53,
45 46, 42, 50, 36, 29, 32 };
46
47 //每轮左移的位数
48 int shiftBits[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
49
50 //E置换表,将32位扩展至48位
51 int E[] = {
52 32, 1, 2, 3, 4, 5,
53 4, 5, 6, 7, 8, 9,
54 8, 9, 10, 11, 12, 13,
55 12, 13, 14, 15, 16, 17,
56 16, 17, 18, 19, 20, 21,
57 20, 21, 22, 23, 24, 25,
58 24, 25, 26, 27, 28, 29,
59 28, 29, 30, 31, 32, 1 };
60
61 //S盒 4x16
62 int S_BOX[8][4][16] = {
63 {
64 { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
65 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
66 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
67 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
68 },
69 {
70 { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
71 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
72 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
73 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
74 },
75 {
76 { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
77 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
78 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
79 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
80 },
81 {
82 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
83 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
84 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
85 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
86 },
87 {
88 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
89 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
90 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
91 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
92 },
93 {
94 { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
95 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
96 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
97 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
98 },
99 {
100 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
101 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
102 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
103 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
104 },
105 {
106 { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
107 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
108 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
109 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
110 }
111 };
112
113 //P置换
114 int P[] = {
115 16, 7, 20, 21,
116 29, 12, 28, 17,
117 1, 15, 23, 26,
118 5, 18, 31, 10,
119 2, 8, 24, 14,
120 32, 27, 3, 9,
121 19, 13, 30, 6,
122 22, 11, 4, 25 };
123
124
125 //密码函数f,接收32位数据和48位子密钥,产生一个32位的输出
126 bitset<32> DES::f(bitset<32> R, bitset<48> k)
127 {
128 bitset<48> expandR;
129 //E
130 for (int i = 0; i<48; ++i)
131 expandR[47 - i] = R[32 - E[i]];
132 //异或
133 expandR = expandR ^ k;
134 //查找S_BOX
135 bitset<32> output;
136 int x = 0;
137 //48 bit分为8组
138 for (int i = 0; i<48; i = i + 6)
139 {
140 // i = x1x6 + 1
141 int row = expandR[47 - i] * 2 + expandR[47 - i - 5];
142 // j = x2x3x4x5 + 1
143 int col = expandR[47 - i - 1] * 8 + expandR[47 - i - 2] * 4 + expandR[47 - i - 3] * 2 + expandR[47 - i - 4];
144 //每个S-盒
145 int num = S_BOX[i / 6][row][col];
146 //转化为bit
147 bitset<4> binary(num);
148 output[31 - x] = binary[3];
149 output[31 - x - 1] = binary[2];
150 output[31 - x - 2] = binary[1];
151 output[31 - x - 3] = binary[0];
152 x += 4;
153 }
154 //P置换
155 bitset<32> tmp = output;
156 for (int i = 0; i<32; ++i)
157 output[31 - i] = tmp[32 - P[i]];
158 return output;
159 }
160
161 //对56位密钥的前后部分进行左移
162 bitset<28> DES::leftShift(bitset<28> k, int shift)
163 {
164 bitset<28> tmp = k;
165 for (int i = 27; i >= 0; --i)
166 {
167 if (i - shift<0)
168 k[i] = tmp[i - shift + 28];
169 else
170 k[i] = tmp[i - shift];
171 }
172 return k;
173 }
174
175 void DES::GetKey(char k[8])
176 {
177 key = charToBitset(k);
178 }
179
180 //将char字符数组转为二进制
181 bitset<64> DES::charToBitset(const char s[8])
182 {
183 bitset<64> bits;
184 for (unsigned i = 0; i < 8; ++i)
185 for (unsigned j = 0; j < 8; ++j)
186 bits[i * 8 + j] = ((s[i] >> j) & 1);
187 return bits;
188 }
189
190 //将二进制转为char字符数组
191 void DES::bitToChar(bitset<64> bits, char c[8])
192 {
193 for (int j = 0; j < 8; j++)
194 c[j] = 0;
195 for (unsigned i = 0; i < 64; i++)
196 {
197 if (bits.test(i)) //该位是否为1
198 c[i / 8] |= 1 << (i % 8);
199 }
200 }
201
202 //生成16个子密钥
203 void DES::generateKeys()
204 {
205 bitset<56> realKey;
206 bitset<28> left;
207 bitset<28> right;
208 bitset<48> compressKey;
209
210 // 去掉奇偶标记位,将64位密钥变成56位
211 for (int i = 0; i<56; ++i)
212 realKey[55 - i] = key[64 - PC_1[i]];
213 // 生成子密钥,保存在 subKeys[16] 中
214 for (int round = 0; round<16; ++round)
215 {
216 // 前28位与后28位
217 for (int i = 28; i<56; ++i)
218 left[i - 28] = realKey[i];
219 for (int i = 0; i<28; ++i)
220 right[i] = realKey[i];
221 // 左移
222 left = leftShift(left, shiftBits[round]);
223 right = leftShift(right, shiftBits[round]);
224 // 压缩置换,由56位得到48位子密钥
225 for (int i = 28; i<56; ++i)
226 realKey[i] = left[i - 28];
227 for (int i = 0; i<28; ++i)
228 realKey[i] = right[i];
229 for (int i = 0; i<48; ++i)
230 compressKey[47 - i] = realKey[56 - PC_2[i]];
231 subKey[round] = compressKey;
232 }
233 /*cout << endl << "16个子密钥:" << endl;
234 for (int i = 0; i < 16; i++)
235 {
236 cout << subKey[i] << endl;
237 }
238 cout << endl;*/
239 }
240
241 //DES加密
242 void DES::encrypt(const char input[8], char output[8])
243 {
244 bitset<64> currentBits;
245 bitset<32> left;
246 bitset<32> right;
247 bitset<32> newLeft;
248
249 plain = charToBitset(input);
250 //初始置换IP
251 for (int i = 0; i<64; ++i)
252 currentBits[63 - i] = plain[64 - IP[i]];
253 //获取 Li 和 Ri
254 for (int i = 32; i<64; ++i)
255 left[i - 32] = currentBits[i];
256 for (int i = 0; i<32; ++i)
257 right[i] = currentBits[i];
258 //16轮迭代
259 for (int round = 0; round<16; ++round)
260 {
261 newLeft = right;
262 right = left ^ f(right, subKey[round]);
263 left = newLeft;
264 }
265 //合并L16和R16,合并为R16L16
266 for (int i = 0; i<32; ++i)
267 cipher[i] = left[i];
268 for (int i = 32; i<64; ++i)
269 cipher[i] = right[i - 32];
270 //尾置换IP-1
271 currentBits = cipher;
272 for (int i = 0; i<64; ++i)
273 cipher[63 - i] = currentBits[64 - IP_1[i]];
274
275 bitToChar(cipher, output);
276 /*cout << "得到密文:" ;
277 for (int i = 0; i < 8; i++)
278 cout << output[i] << endl;*/
279 }
280 //DES解密
281 void DES::decrypt(const char input[8], char output[8])
282 {
283 bitset<64> currentBits;
284 bitset<32> left;
285 bitset<32> right;
286 bitset<32> newLeft;
287
288 cipher = charToBitset(input);
289 //初始置换IP
290 for (int i = 0; i<64; ++i)
291 currentBits[63 - i] = cipher[64 - IP[i]];
292 //获取 Li 和 Ri
293 for (int i = 32; i<64; ++i)
294 left[i - 32] = currentBits[i];
295 for (int i = 0; i<32; ++i)
296 right[i] = currentBits[i];
297 //共16轮迭代(子密钥逆序应用)
298 for (int round = 0; round<16; ++round)
299 {
300 newLeft = right;
301 right = left ^ f(right, subKey[15 - round]);
302 left = newLeft;
303 }
304 //合并L16和R16,合并为R16L16
305 for (int i = 0; i<32; ++i)
306 plain[i] = left[i];
307 for (int i = 32; i<64; ++i)
308 plain[i] = right[i - 32];
309 //尾置换IP-1
310 currentBits = plain;
311 for (int i = 0; i<64; ++i)
312 plain[63 - i] = currentBits[64 - IP_1[i]];
313
314 bitToChar(plain, output);
315 /*cout << "得到密文解:";
316 for (int i = 0; i < 8; i++)
317 cout << output[i] << endl;*/
318 }
319
320 //string任意长明文加密
321 void DES::StrEncrypt(string plaintext, string &ciphertext)
322 {
323 char output[8];
324 string stradd = " ";
325 string per = output;
326 int length = plaintext.length();
327 if (length % 8 != 0)
328 {//明文不是8的倍数,用空格填充
329 plaintext.append(stradd, 0, 8 - length % 8);
330 }
331 length = plaintext.length();
332 for (int i = 0; i < length; i += 8)
333 {
334 per = plaintext.substr(i, 8);
335 encrypt(per.c_str(),output);
336 per = output;
337 ciphertext += per.substr(0,8);
338 }
339 }
340
341 //string任意长密文解密
342 void DES::StrDecrypt(string ciphertext, string &output)
343 {
344 char out[8];
345 string per = out;
346 int length = ciphertext.length();
347 for (int i = 0; i < length; i += 8)
348 {
349 per = ciphertext.substr(i, 8);
350 decrypt(per.c_str(), out);
351 per = out;
352 output += per.substr(0,8);
353 }
354 }