本来没兴趣(其实时太菜)去看密码学这些东西的,但是刚好密码学老师布置了一个DES分析的作业,本来是打算水一水,抄点PPT啥的交了完事,最后还是觉得有必要学习一下,顺便练习一下py,就有了这篇划水博客
发展历史及一些基本信息
1971年,IBM讲LUCIFER密码改进成为建议的DES体制
1975年3月17日,MBS公布该算法
1977年1月15日建议被批准为联邦标准,设计推出DES芯片
1981年,ISO将其作为标准,简称DEA-1
NSA宣布每隔5年重新审议DES是否继续作为联邦标准
- 1988 => FIPS46-1
- 1993 => FIPS46-2
- 1998 => 不再批准
DES虽然已有替代标准,单它仍是迄今为止得到最为广泛应用的一种算法,是一种最有代表性的分组加密体制
DES是第一代公开的,完全说明细节的商业级现代密码
DES算法分析
明文 => 64位一组进行分组 => IP置换 => 密钥置换 => E扩展置换 =>S盒代替 =>P盒置换 => 重复16轮 => 末置换
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 |
这个置换的含义是讲,原64位明文中某一位数据放到另一个位置上,比如,明文第一位经过置换后移动到了第40位,明文中的第58位则移动到了第一位,并以此类推,最后再将原来的64位数据对半分为两组32位数据,标注位L0和R0,进入下一次加密
密钥置换
在DES中,有效密钥的长度位56位,具体的原因是因为,在密钥中,每个字节的第8位是作为奇偶校验位的,所以有效密钥就只有64-8=56,所以在下面这个表中也会缺少8、16、24、32、40、48、56、64
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 |
讲56位密钥按上表进行置换后,会从置换后的密钥中生成不同的48位子密钥,子密钥产生过程:
- 将56位密钥分为两组,每组28位
- 根据加密的第几轮,让每组密钥左移对应位数
轮数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
位数 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 |
轮数 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
位数 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 1 |
- 经过移动后,我们又将得到的56位密钥除第8,18,22,25,35,38,43,54这8位以外的的字符进行一次置换,就得到了一个48位的密钥,使用该密钥与48位待加密内容进行异或
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 | 42 |
E扩展置换
这一轮将IP置换的右半部分R0,32位(4*8)扩展为48位,如下图,即将第32位和5位加到新的内容中的第一和第6位,每一行都是如此
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 |
经过拓展之后变为48位的R0位数和密钥位数相同,继续将48位的R0和48位的密钥进行异或,进入下一步
S盒代替
将上一步异或后得到的48位数据,经过S盒进行替代运算,在这里48位的数据分为68,8组分别送入8个不同的S盒,每个盒输出6位数据,共输出48=32位数据,先给出8个S盒
s1
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 |
S2
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 |
S3
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 |
S4
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 | 19 |
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 |
S5
2 | 12 | 4 | 1 | 7 | 10 | 11 | 6 | 5 | 8 | 3 | 15 | 13 | 0 | 14 | 9 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
14 | 11 | 2 | 12 | 4 | 7 | 13 | 1 | 5 | 0 | 15 | 13 | 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 |
S6
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 |
S7
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 |
S8
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 |
我们已S8为例,假设输入的6位数据为 111111,第一位和第六位组合为11,即为十进制的3,对应S盒的第四行,中间4为1111即为16进制的15,对应第16列,这里我们的得到11,输出二进制1011,这样就完成了一个6转4的过程,8个S盒拼起来,就是32位数据,送入下一步
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 |
将置换后的32位数据与最开始的32位左半部分L0进行异或得到一个新的32位数据
将这个32位数据作为新一轮的R,上一轮的R作为新一轮的L,即:
RO => L1
加密后的R0 => R1
末置换(逆IP置换)
初始置换的逆过程,DES最后一轮后,左、右两半部分并未进行交换,而是两部分合并形成一个分组做为末置换的输入
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 |
置换后就可以得到密文
关于解密
解密时需要注意得是,16轮与密钥异或是,密钥顺序要和加密时相反
code
1 | IP_table=[58,50,42,34,26,18,10,2, |