标签:
DES算法是一种通用的对称密钥算法,加解密的密钥是相同的。明文长度64比特,密钥长度为56比特,加密后密文长度是64比特。
1.初始置换IP
IP[] = { 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 };
2.子密钥Ki获取:
PC-1表示从64 Bit中选出56 Bit密钥,分为前28位 C0 和后28位 D0,分别对它们进行循环左移,C0左移得到 C1,D0 左移得到 D1。
将 C1 和 D1 合并成 56 位,然后通过
PC-2
表进行压缩置换,得到当前这一轮的 48 位子密钥 K1 。然后对 C1 和 D1 进行左移和压缩置换,获取下一轮的子密钥……一共进行16轮,得到 16 个 48 位的子密钥。
PC_1[] = {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_2[] = {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};
3.密码函数 f (R, K):
E进行扩展置换,将32位扩展至48位
E[] = {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};
8个S盒
S_BOX[8][4][16] = { { {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,0,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} } };
P盒替代,用法与IP类似
P[] = {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 };
4.尾置换IP-1 :
IP_1[] = {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};
1 #include <iostream> 2 #include <fstream> 3 #include <bitset> 4 #include <string> 5 using namespace std; 6 7 bitset<64> key; // 64位密钥 8 bitset<48> subKey[16]; // K1~K16子密钥 9 //IP置换表 10 int IP[] = { 11 58, 50, 42, 34, 26, 18, 10, 2, 12 60, 52, 44, 36, 28, 20, 12, 4, 13 62, 54, 46, 38, 30, 22, 14, 6, 14 64, 56, 48, 40, 32, 24, 16, 8, 15 57, 49, 41, 33, 25, 17, 9, 1, 16 59, 51, 43, 35, 27, 19, 11, 3, 17 61, 53, 45, 37, 29, 21, 13, 5, 18 63, 55, 47, 39, 31, 23, 15, 7 }; 19 //IP-1置换表 20 int IP_1[] = { 21 40, 8, 48, 16, 56, 24, 64, 32, 22 39, 7, 47, 15, 55, 23, 63, 31, 23 38, 6, 46, 14, 54, 22, 62, 30, 24 37, 5, 45, 13, 53, 21, 61, 29, 25 36, 4, 44, 12, 52, 20, 60, 28, 26 35, 3, 43, 11, 51, 19, 59, 27, 27 34, 2, 42, 10, 50, 18, 58, 26, 28 33, 1, 41, 9, 49, 17, 57, 25 }; 29 //将64位密钥变成56位 30 int PC_1[] = { 31 57, 49, 41, 33, 25, 17, 9, 32 1, 58, 50, 42, 34, 26, 18, 33 10, 2, 59, 51, 43, 35, 27, 34 19, 11, 3, 60, 52, 44, 36, 35 63, 55, 47, 39, 31, 23, 15, 36 7, 62, 54, 46, 38, 30, 22, 37 14, 6, 61, 53, 45, 37, 29, 38 21, 13, 5, 28, 20, 12, 4 }; 39 40 //将56位密钥压缩成48位子密钥 41 int PC_2[] = { 42 14, 17, 11, 24, 1, 5, 43 3, 28, 15, 6, 21, 10, 44 23, 19, 12, 4, 26, 8, 45 16, 7, 27, 20, 13, 2, 46 41, 52, 31, 37, 47, 55, 47 30, 40, 51, 45, 33, 48, 48 44, 49, 39, 56, 34, 53, 49 46, 42, 50, 36, 29, 32 }; 50 //每轮左移的位数 51 int shiftBits[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; 52 //E置换表,将32位扩展至48位 53 int E[] = { 54 32, 1, 2, 3, 4, 5, 55 4, 5, 6, 7, 8, 9, 56 8, 9, 10, 11, 12, 13, 57 12, 13, 14, 15, 16, 17, 58 16, 17, 18, 19, 20, 21, 59 20, 21, 22, 23, 24, 25, 60 24, 25, 26, 27, 28, 29, 61 28, 29, 30, 31, 32, 1 }; 62 //S盒 4x16 63 int S_BOX[8][4][16] = { 64 { 65 { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, 66 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, 67 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, 68 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } 69 }, 70 { 71 { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, 72 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, 73 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, 74 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } 75 }, 76 { 77 { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, 78 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, 79 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, 80 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } 81 }, 82 { 83 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, 84 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, 85 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, 86 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } 87 }, 88 { 89 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, 90 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, 91 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, 92 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } 93 }, 94 { 95 { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, 96 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, 97 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, 98 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } 99 }, 100 { 101 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, 102 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, 103 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, 104 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } 105 }, 106 { 107 { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, 108 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, 109 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, 110 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } 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 //密码函数f,接收32位数据和48位子密钥,产生一个32位的输出 125 bitset<32> f(bitset<32> R, bitset<48> k) 126 { 127 bitset<48> expandR; 128 //E 129 for (int i = 0; i<48; ++i) 130 expandR[47 - i] = R[32 - E[i]]; 131 //异或 132 expandR = expandR ^ k; 133 //查找S_BOX 134 bitset<32> output; 135 int x = 0; 136 for (int i = 0; i<48; i = i + 6) 137 { 138 int row = expandR[47 - i] * 2 + expandR[47 - i - 5]; 139 int col = expandR[47 - i - 1] * 8 + expandR[47 - i - 2] * 4 + expandR[47 - i - 3] * 2 + expandR[47 - i - 4]; 140 int num = S_BOX[i / 6][row][col]; 141 bitset<4> binary(num); 142 output[31 - x] = binary[3]; 143 output[31 - x - 1] = binary[2]; 144 output[31 - x - 2] = binary[1]; 145 output[31 - x - 3] = binary[0]; 146 x += 4; 147 } 148 //P置换 149 bitset<32> tmp = output; 150 for (int i = 0; i<32; ++i) 151 output[31 - i] = tmp[32 - P[i]]; 152 return output; 153 } 154 //对56位密钥的前后部分进行左移 155 bitset<28> leftShift(bitset<28> k, int shift) 156 { 157 bitset<28> tmp = k; 158 for (int i = 27; i >= 0; --i) 159 { 160 if (i - shift<0) 161 k[i] = tmp[i - shift + 28]; 162 else 163 k[i] = tmp[i - shift]; 164 } 165 return k; 166 } 167 //生成16个子密钥 168 void generateKeys() 169 { 170 bitset<56> realKey; 171 bitset<28> left; 172 bitset<28> right; 173 bitset<48> compressKey; 174 // 去掉奇偶标记位,将64位密钥变成56位 175 for (int i = 0; i<56; ++i) 176 realKey[55 - i] = key[64 - PC_1[i]]; 177 // 生成子密钥,保存在 subKeys[16] 中 178 for (int round = 0; round<16; ++round) 179 { 180 // 前28位与后28位 181 for (int i = 28; i<56; ++i) 182 left[i - 28] = realKey[i]; 183 for (int i = 0; i<28; ++i) 184 right[i] = realKey[i]; 185 // 左移 186 left = leftShift(left, shiftBits[round]); 187 right = leftShift(right, shiftBits[round]); 188 // 压缩置换,由56位得到48位子密钥 189 for (int i = 28; i<56; ++i) 190 realKey[i] = left[i - 28]; 191 for (int i = 0; i<28; ++i) 192 realKey[i] = right[i]; 193 for (int i = 0; i<48; ++i) 194 compressKey[47 - i] = realKey[56 - PC_2[i]]; 195 subKey[round] = compressKey; 196 } 197 } 198 //将char字符数组转为二进制 199 bitset<64> charToBitset(const char s[8]) 200 { 201 bitset<64> bits; 202 for (int i = 0; i<8; ++i) 203 for (int j = 0; j<8; ++j) 204 bits[i * 8 + j] = ((s[i] >> j) & 1); 205 return bits; 206 } 207 //DES加密 208 bitset<64> encrypt(bitset<64>& plain) 209 { 210 bitset<64> cipher; 211 bitset<64> currentBits; 212 bitset<32> left; 213 bitset<32> right; 214 bitset<32> newLeft; 215 //初始置换IP 216 for (int i = 0; i<64; ++i) 217 currentBits[63 - i] = plain[64 - IP[i]]; 218 //获取 Li 和 Ri 219 for (int i = 32; i<64; ++i) 220 left[i - 32] = currentBits[i]; 221 for (int i = 0; i<32; ++i) 222 right[i] = currentBits[i]; 223 //16轮迭代 224 for (int round = 0; round<16; ++round) 225 { 226 newLeft = right; 227 right = left ^ f(right, subKey[round]); 228 left = newLeft; 229 } 230 //合并L16和R16,合并为R16L16 231 for (int i = 0; i<32; ++i) 232 cipher[i] = left[i]; 233 for (int i = 32; i<64; ++i) 234 cipher[i] = right[i - 32]; 235 //尾置换IP-1 236 currentBits = cipher; 237 for (int i = 0; i<64; ++i) 238 cipher[63 - i] = currentBits[64 - IP_1[i]]; 239 //返回密文 240 return cipher; 241 } 242 //DES解密 243 bitset<64> decrypt(bitset<64>& cipher) 244 { 245 bitset<64> plain; 246 bitset<64> currentBits; 247 bitset<32> left; 248 bitset<32> right; 249 bitset<32> newLeft; 250 //初始置换IP 251 for (int i = 0; i<64; ++i) 252 currentBits[63 - i] = cipher[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[15 - round]); 263 left = newLeft; 264 } 265 //合并L16和R16,合并为R16L16 266 for (int i = 0; i<32; ++i) 267 plain[i] = left[i]; 268 for (int i = 32; i<64; ++i) 269 plain[i] = right[i - 32]; 270 //尾置换IP-1 271 currentBits = plain; 272 for (int i = 0; i<64; ++i) 273 plain[63 - i] = currentBits[64 - IP_1[i]]; 274 //返回明文 275 return plain; 276 } 277 /* 278 Test: 279 密文写入a.txt 280 解密写入b.txt 281 */ 282 void main(void) 283 { 284 string s = "HangZhou"; //限8个字母,64位 285 string k = "secret"; 286 bitset<64> plain = charToBitset(s.c_str()); 287 key = charToBitset(k.c_str()); 288 //生成子密钥 289 generateKeys(); 290 bitset<64> cipher = encrypt(plain); 291 fstream file1; 292 file1.open("E://a.txt", ios::binary | ios::out); 293 file1.write((char*)&cipher, sizeof(cipher)); 294 file1.close(); 295 296 bitset<64> temp; 297 file1.open("E://a.txt", ios::binary | ios::in); 298 file1.read((char*)&temp, sizeof(temp)); 299 file1.close(); 300 301 bitset<64> temp_plain = decrypt(temp); 302 file1.open("E://b.txt", ios::binary | ios::out); 303 file1.write((char*)&temp_plain, sizeof(temp_plain)); 304 file1.close(); 305 }
标签:
原文地址:http://www.cnblogs.com/ht-beyond/p/4328268.html