码迷,mamicode.com
首页 > 其他好文 > 详细

DES

时间:2015-03-10 21:05:12      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

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 }

 

DES

标签:

原文地址:http://www.cnblogs.com/ht-beyond/p/4328268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!