# 流密码
逐位加密信息,将明文消息分解为单个位,然后使用密钥位将其分别转换为密文。流密码一次加密一位数据,而不用等待数据块的形成,此过程的关键在于根据加密密钥和种子(随机数 nonce
)生成伪随机比特流,它们一起创建了一个密钥流(伪随机比特流),该密钥流再与纯文本逐位进行异或运算,生成密文。因为每个数字的加密都取决于密码引擎的当前状态,所以流密码也被称为状态密码。
# 分组密码
顾名思义,分块加密信息;分组密码将明文消息分解为固定大小的块 block
,然后使用密钥将其转换为密文。例如,当提供了一个 x
位分块纯文本(连同一个密钥)作为块密码引擎的输入时,它会生成相应的 x
位密文块,此过程依赖于密钥,同样解密算法利用 x
位分块密文和上述密钥作为输入,恢复原始的 x
位。每块使用相同的密钥(单独)加密,但是由于使用了相同的密钥,所以纯文本中的每个重复序列都转换成了密码本中相同的重复序列,可能会引起安全问题。流行的块密码是 DES
(数据加密标准)和 AES
(高级加密标准)。
# 对比
流密码通常比分组密码执行得更快,当纯文本以不同数量可用时,比如一个安全的 WIFI
连接,流密码展现出比分组密码更大的优势,因为分组密码不能直接对小于块大小的块进行操作。但有时候,它们之间的差别不是很明显,这是因为当使用某些操作模式时,分组密码可以用作流密码,允许它加密可用的最小数据单元。
# DES 加密算法
该加密算法中,明文和密文为 64
位的文组文本,密钥长度也为 64
位,但是密钥的每组第 8
个位置设置为奇偶校验位,因而密钥实际长度为 56
位。
加密过程如下
初始置换
生成子密钥
迭代
逆置换
# 初始置换
将原文本经过 IP
置换表处理
58,50,42,34,26,18,10,02,
60,52,44,36,28,20,12,04,
62,54,46,38,30,22,14,06,
64,56,48,40,32,24,16,08,
57,49,41,33,25,17,09,01,
59,51,43,35,27,19,11,03,
61,53,45,37,29,21,13,05,
63,55,47,39,31,23,15,07,
例如如下 64
位的明文 M
M = 0110001101101111011011010111000001110101011101000110010101110010 | |
--- | |
M' = 1111111110111000011101100101011100000000111111110000011010000011 | |
L0 = 11111111101110000111011001010111 | |
R0 = 00000000111111110000011010000011 |
在初始排列之后,我们有两个 32
位纯文本区域,分别称为左纯文本 L0
和右纯文本 R0
。
# 子密钥生成
每次迭代过程的数据长度为 48
位,因此需要 16
个 48
位的子密钥来进行加密,生成子密钥的过程如下
PC-1 表
去除校验位后,密钥第一轮置换, PC-1
表 8*7
,密钥 K
经 PC-1
后变为 56
位数据 K0
。
57,49,41,33,25,17,09
01,58,50,42,34,26,18
10,02,59,51,43,35,27
19,11,03,60,52,44,36
63,55,47,39,31,23,15
07,62,54,46,38,30,22
14,06,61,53,45,37,29
21,13,05,28,20,12,04
Shift 表
某一轮左移位数
PC-2 表
由于 PC-2
表为 8*6
的表,经 PC-2
置换后的数据为 48
位,置换后得到子密钥 K1
, PC-2
表中去除了第 9,18,22,25,35,38,43,54
位。
14,17,11,24,01,05,
03,28,15,06,21,10,
23,19,12,04,26,08,
16,07,27,20,13,02,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32
例如
K = 0001001100110100010101110111100110011011101111001101111111110001 | |
第一轮置换 | |
去除校验位,经过PC-1置换 | |
K0 = 11110000110011001010101011110101010101100110011110001111 | |
C0 = 1111000011001100101010101111 | |
D0 = 0101010101100110011110001111 | |
进行第一轮移位,左移1位 | |
C1 = 1110000110011001010101011111 | |
D1 = 1010101011001100111100011110 | |
CD_1 = 11100001100110010101010111111010101011001100111100011110 (56位) | |
C1与D1合并,经过第一轮PC-2置换,去除了第9,18,22,25,35,38,43,54位 | |
K1 = 000110110000001011101111111111000111000001110010 (48位) | |
第二轮置换 | |
进行第二轮移位,左移1位 | |
C2 = 1100001100110010101010111111 | |
D2 = 0101010110011001111000111101 | |
CD_2 = 11000011001100101010101111110101010110011001111000111101 (56位) | |
C2与D2合并,经过第二轮PC-2置换,去除了第9,18,22,25,35,38,43,54位 | |
K2 = 011110011010111011011001110110111100100111100101 | |
C3(28位) = 0000110011001010101011111111 | |
D3(28位) = 0101011001100111100011110101 | |
K3(48位) = 010101011111110010001010010000101100111110011001 | |
C4(28位) = 0011001100101010101111111100 | |
D4(28位) = 0101100110011110001111010101 | |
K4(48位) = 011100101010110111010110110110110011010100011101 | |
以此类推 |
# 迭代
设 Li
( 32
位)和 Ri
( 32
位)为第 i 次迭代结果的左半部分与右半部分,子密钥 Ki
为第 i
轮的 48
位加密密钥。定义运算规则:
Li = Ri-1;
Ri = Li ⊕ f(Ri-1, Ki);
# 扩展置换 E
DES
加密共执行 16
轮迭代,每次迭代过程的数据长度 48
位,然而初始置换完后每一半的长度为 32
位,如何扩展成 48
位?只是因为 32
位 R0
被分为 8
个块,每个块 4
位,每个块首尾各添加 1
个位,即可满足要求。
32, 01, 02, 03, 04, 05,
04, 05, 06, 07, 08, 09,
08, 09, 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, 01
# Expansion D-box Table | |
exp_d = [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 ] | |
# Permute function to rearrange the bits | |
def permute(k, arr, n): | |
permutation = "" | |
for i in range(0, n): | |
permutation = permutation + k[arr[i] - 1] | |
return permutation | |
for i in range(0, 16): | |
# Expansion D-box: Expanding the 32 bits data into 48 bits | |
right_expanded = permute(right, exp_d, 48) |
例如
R0 = 0000 0000 1111 1111 0000 0110 1000 0011 | |
--- | |
E(R0)^k1 = 100000 000001 011111 111110 100000 001101 010000 000110 |
# S-BOX
由 8
个不同的代替盒( S
盒)完成。每个 S
盒有 6
位输入, 4
位输出。代替运算流程如下
若 S-盒1
的输入为 110111
,第一位与最后一位构成 11
,十进制值为 3
,则对应第 3
行,中间 4
位为 1011
对应的十进制值为 11
,则对应第 11
列。查找 S-盒1
表的值为 14
,则 S - 盒 1 的输出为 1110
。 8
个 S盒
将输入的 48
位数据输出为 32
位数据。
S - 盒 1
14,04,13,01,02,15,11,08,03,10,06,12,05,09,00,07,
00,15,07,04,14,02,13,01,10,06,12,11,09,05,03,08,
04,01,14,08,13,06,02,11,15,12,09,07,03,10,05,00,
15,12,08,02,04,09,01,07,05,11,03,14,10,00,06,13,
S - 盒 2
15,01,08,14,06,11,03,04,09,07,02,13,12,00,05,10,
03,13,04,07,15,02,08,14,12,00,01,10,06,09,11,05,
00,14,07,11,10,04,13,01,05,08,12,06,09,03,02,15,
13,08,10,01,03,15,04,02,11,06,07,12,00,05,14,09,
S - 盒 3
10,00,09,14,06,03,15,05,01,13,12,07,11,04,02,08,
13,07,00,09,03,04,06,10,02,08,05,14,12,11,15,01,
13,06,04,09,08,15,03,00,11,01,02,12,05,10,14,07,
01,10,13,00,06,09,08,07,04,15,14,03,11,05,02,12,
S - 盒 4
07,13,14,03,00,06,09,10,01,02,08,05,11,12,04,15,
13,08,11,05,06,15,00,03,04,07,02,12,01,10,14,09,
10,06,09,00,12,11,07,13,15,01,03,14,05,02,08,04,
03,15,00,06,10,01,13,08,09,04,05,11,12,07,02,14,
S - 盒 5
02,12,04,01,07,10,11,06,08,05,03,15,13,00,14,09,
14,11,02,12,04,07,13,01,05,00,15,10,03,09,08,06,
04,02,01,11,10,13,07,08,15,09,12,05,06,03,00,14,
11,08,12,07,01,14,02,13,06,15,00,09,10,04,05,03,
S - 盒 6
12,01,10,15,09,02,06,08,00,13,03,04,14,07,05,11,
10,15,04,02,07,12,09,05,06,01,13,14,00,11,03,08,
09,14,15,05,02,08,12,03,07,00,04,10,01,13,11,06,
04,03,02,12,09,05,15,10,11,14,01,07,06,00,08,13,
S - 盒 7
04,11,02,14,15,00,08,13,03,12,09,07,05,10,06,01,
13,00,11,07,04,09,01,10,14,03,05,12,02,15,08,06,
01,04,11,13,12,03,07,14,10,15,06,08,00,05,09,02,
06,11,13,08,01,04,10,07,09,05,00,15,14,02,03,12,
S - 盒 8
13,02,08,04,06,15,11,01,10,09,03,14,05,00,12,07,
01,15,13,08,10,03,07,04,12,05,06,11,00,14,09,02,
07,11,04,01,09,12,14,02,00,06,10,13,15,03,05,08,
02,01,14,07,04,10,08,13,15,12,09,00,03,05,06,11,
例如
E(R0)^k1 = 100000 000001 011111 111110 100000 001101 010000 000110 | |
S(E(R0)^k1) = 1000 1011 1100 0100 0110 0010 1110 1010 |
# P-BOX
将 S-盒
替代的输出结果作为 P-盒
置换的输入。 P-盒
置换表如下:
16,07,20,21,29,12,28,17,01,15,23,26,05,18,31,10,
02,08,24,14,32,27,03,09,19,13,30,06,22,11,04,25,
将S盒输出10001011110001000110001011101010(32位)经过P盒置换, | |
P-盒置换输出01001000101111110101010110000001 | |
令扩展置换E、S-盒替代、P盒置换的过程作为函数f。 | |
第一次迭代过程f(R0,K1)为: | |
f(R0,K1) = 01001000101111110101010110000001 | |
计算L1(32位) = R0 = 00000000111111110000011010000011 | |
计算R1(32位) = L0 ^ f(R0,K1) | |
11111111101110000111011001010111 | |
01001000101111110101010110000001 | |
= 10110111000001110010001111010110 | |
R1(32位) = 10110111000001110010001111010110。 | |
将L1与R1作为输入,继续执行迭代过程f。直至输出L16与R16。 | |
经过16次迭代后输出: | |
L16(32位) = 00110000100001001101101100101000 | |
R16(32位) = 10110001011001010011000000011000 |
# 逆置换
将初始置换进行 16
次的迭代,即进行 16
层的加密变换,得到 L16
和 R16
,将此作为输入块,进行逆置换得到最终的密文输出块。逆置换是初始置换的逆运算。从初始置换规则中可以看到,原始数据的第 1
位置换到了第 40
位,第 2
位置换到了第 8
位。则逆置换就是将第 40
位置换到第 1
位,第 8
位置换到第 2
位。以此类推,逆置换规则表如下
40,08,48,16,56,24,64,32,
39,07,47,15,55,23,63,31,
38,06,46,14,54,22,62,30,
37,05,45,13,53,21,61,29,
36,04,44,12,52,20,60,28,
35,03,43,11,51,19,59,27,
34,02,42,10,50,18,58 26,
33,01,41,09,49,17,57,25,
将 L16
与 R16
构成 64
位数据,经过逆置换表输出密文为:
密文
0101100000001000001100000000101111001101110101100001100001101000