DES
1 /* 2 2015.4 3 DES加解密类 4 */ 5 #ifndef DES_H 6 #define DES_H 7 8 #include <iostream> 9 #include <string> 10 #include <bitset> 11 using namespace std; 12 13 class DES 14 { 15 public: 16 void GetKey(char k[8]); 17 //生成16个子密钥 18 void generateKeys(); 19 20 void encrypt(const char input[8], char output[8]); 21 void decrypt(const char input[8], char output[8]); 22 23 void StrEncrypt(string plaintext, string &ciphertext); 24 void StrDecrypt(string ciphertext, string &output); 25 26 private: 27 bitset<64> key; // 64位密钥 28 bitset<48> subKey[16]; // K1~K16子密钥 29 bitset<64> plain; 30 bitset<64> cipher; 31 32 bitset<64> charToBitset(const char s[8]); 33 void bitToChar(bitset<64> bits, char c[8]); 34 35 //圈函数 36 bitset<32> f(bitset<32> R, bitset<48> k); 37 bitset<28> leftShift(bitset<28> k, int shift); 38 39 }; 40 41 #endif
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 }
1 #include <iostream> 2 #include <string> 3 #include "DES.h" 4 using namespace std; 5 6 7 int main() 8 { 9 DES des; 10 char key[8]; 11 string k; 12 string plaintext, ciphertext, output; 13 14 cout << "输入明文: "; 15 cin >> plaintext; 16 cout << "输入密钥: "; 17 for (int i = 0; i < 8; i++) 18 cin >> key[i]; 19 des.GetKey(key); 20 des.generateKeys(); 21 22 des.StrEncrypt(plaintext, ciphertext); 23 cout << endl << "输出密文: " << ciphertext.c_str() << endl; 24 des.StrDecrypt(ciphertext, output); 25 cout << endl << "解密密文: " << output.c_str() << endl; 26 27 cout << endl; 28 return 0; 29 }