DES加密的过程

最近经常要使用DES或者3DES加密,虽然有现成的工具可以使用,但就是忍不住要看看加密的原理是啥,过程是怎么样的。有人说我又重复造轮子了,而且这造出来的轮子不圆。

首先千万别参考维基百科的条目,那个条目不管是中文还是英文都写得乱七八糟,看完还不知道整个过程到底是如何进行,而且在表述的时候还有诸多歧义。

下面举个例子来说明加密的过程。

明文:52 61 69 73 75 69 73 65
密钥:3b 38 98 37 15 20 f7 5e
密文:bc 72 47 49 83 36 0e a8

首先将明文转化成二进制,即:

0101 0010
0110 0001
0110 1001
0111 0011
0111 0101
0110 1001
0111 0011
0110 0101

然后经初始置换(IP),变成:

1111 1111
0101 1001
1001 0000
1111 1110
0000 0000
1111 1110
0010 0100
0100 1001

然后我们要生成16个子密钥,原来的密钥是:

0011 1011
0011 1000
1001 1000
0011 0111
0001 0101
0010 0000
1111 0111
0101 1110

经过两个置换(PC-1)将64位的密钥分成两个28位的内容:

0100010
0110000
0001101
0111101

1100100
1110110
0010000
1111111

然后把置换后的两部分都进行左移(移动的位数后边再说明),左移之后合并成一个56位的内容,然后经过的选择置换(PC-2)就生成了子密钥key[0]:

010111 000000 100001 001100
010101 011000 111101 001111

不同的子密钥只是左移的位数不同,如下边所示:

密钥编号: 0 1 2 3 4 5  6  7  8  9  10 11 12 13 14 15
左移位数: 1 2 4 6 8 10 12 14 15 17 19 21 23 25 27 28

因此key[1]、key[2]……key[15]分别是:

010100 010010 110111 110000
011001 001001 011111 001100

110101 001110 010010 000101
110110 001011 010011 101111

……

000100 010111 110010 000001
110101 111110 000101 001110

接下来是使用费斯妥函数,过程稍微有点复杂,前面明文进行一次IP置换后,将结果拆成左右两个32位数据(L0与R0),然后将R0经过扩张函数(E)置换,置换后与key[0]进行异或运算,变成:

110111 000001 111110 110000
010001 010000 110100 011101

将结果使用S盒进行处理,处理后为:

1110 0011 0111 1111
0101 0000 0110 1001

接着重组(P置换)为:

1110 1100 1101 0101
1101 1110 0100 0100

最后与L0异或,生成R1,而之前R0直接等于L1。这个过程同样要重复16次,每一次的内容如下(经过S盒置换结果,L[n],R[n]):

Round 1:
1110 0011 0111 1111 0101 0000 0110 1001
00000000 11111110 00100100 01001001
00010011 10001100 01001110 10111010

Round 2:
1100 0111 1110 1100 1000 0011 1111 1111
00010011 10001100 01001110 10111010
01001011 01001101 11011001 00111100

Round 3:
0101 1100 0101 1111 1101 0110 0110 1011
01001011 01001101 11011001 00111100
10111110 11110011 11010010 11100000

……

Round 16:
1100 1100 1110 0011 1011 1100 0100 0001
10010001 10100011 11001001 01110110
00001110 00100011 01100101 00011100

要注意生成L16与R16之后,要再次交换两者的位置,再合并成一个64位数据,最后经过最终置换(FP)就生成密文:

10111100
01110010
01000111
01001001
10000011
00110110
00001110
10101000

另外还有S盒的使用方法:将一个48位的数据分成8个6位,每个6位经过S盒的置换后变成4位,再合并起来就是32位。S盒为一个16x4的矩阵,取6位数据的首末两位作为行,中间4位作为列,然后从表里查到相应的数字转化成二进制就是置换后输出的内容。如上边例子中第一个需要处理内容是110111,从S1的表中横向取1011,纵向取11,结果是14,再转成1110输出。

关于上文提到的各种变换以及S盒的内容详见DES补充材料