DES加密详细解析
标签(空格分隔): DES
DES概述
64位明文明文分组进行16轮完全相同的变换(轮函数)
56位有效密钥长度(外加8位奇偶校验位,总输入为64位)。
分组长度:64位
加密核心流程
整体流程如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
64位明文
|
↓
初始置换(IP)
|
↓
将64位分为左半(L0)、右半(R0),各32位
|
|----------------------|
| |
↓ (16轮迭代) ↓
L[i] = R[i-1] R[i] = L[i-1] ⊕ F(R[i-1], K[i])
| |
|----------------------|
| (i从1到16)
↓
16轮后,交换左右(L16, R16)→(R16, L16)
|
↓
末置换(IP⁻¹,即IP的逆置换)
|
↓
64位密文
1 | 64位明文 |
首先密匙的处理
首先提供64位的密匙(通常是8字节的密匙),在每一个字节的编码为长度为8的2进制值,而此时每个字节的第8位是奇偶检验位。
对密匙进行PC-1置换
此时在PC-1置换的过程中每个字节的第8位(奇偶检验位舍去),PC-1表是一个标准且固定的表。下面以每个字节(1-64排序去除奇偶检验位)呈现
1 | // 左半部分 C₀ 的来源位置(位的位置编号从1开始) |
此时将前28个分为$C_{0}$和$D_{0}$
然后进行偏移生成所有的$C_{n}$和$D_{n}$
在DES的16轮加密的时候每一轮对C和D循环左移位数是预先定义好的。
| 轮数 (Round i) | 左移位数 (Shift Amount) |
|---|---|
| 1, 2, 9, 16 | 1位 |
| 其他所有轮 (3,4,5,6,7,8,10,11,12,13,14,15) | 2位 |
| 记忆技巧:只有第1、2、9、16轮移1位,其他都移2位。 |
1 | 左移的情况 |
K[i]的生成
此时会通过PC-2生成K[i],PC-2是固定的,如下
1 | 14 17 11 24 1 5 |
现在以k[1]的生成为例
1 | C1 = 1110000110011001010101011111 |
就可以生成k[i]了。由于进行了16轮对密匙的处理,我们得到了16个子密匙。然后通常我们把密匙写成16进制可以得到以下类似的子密匙
1 | K[1] = 1B02EFFC7072 |
明文的处理
填充
先将明文利用ASCLL值换为二进制。但是由于DES加密每一次只能对8个长度的数据块进行加密。所以会将剩下的数据块进行填充。
比如剩下m长度数据块,则剩下8-m长度的数据块的值都为8-m。然后就可以填充成为一个长度为8的数据块
然后对明文进行初始置换IP
明文置换的IP表是一定的所以我们用原始明文顺序从1-64来表示
1 | 58 50 42 34 26 18 10 2 |
然后再分为L0和R0如下
1 | IP(M) = 11001100 00000000 11001100 11111111 |
16轮Feistel迭代
假设当前是第i轮(i从1到16),我们有:
输入:Lᵢ₋₁(左32位),Rᵢ₋₁(右32位)
子密钥:Kᵢ(48位,由密钥调度算法生成)
由于迭代会有些复杂我将把每一步列出来
第一步
1 | 复制Rᵢ₋₁(32位)作为轮函数F的输入 |
第二步
1 | Rᵢ₋₁ (32位) → [E盒扩展] → E(Rᵢ₋₁) (48位) |
E盒拓展: 直观规律:每组的第1位来自前一组最后1位,第6位来自后一组第1位
具体数值变成这样
1 | 输入32位的位置: 1 2 3 4 5 6 7 8 ... 32 |
第三步
与子密匙异或
1 | E(Rᵢ₋₁) ⊕ Kᵢ = 48位中间结果 |
第四步
将48位结果分成8个6位组,每组送入一个不同的S盒(S1-S8)
S盒的结构
数量: DES共有 8个不同的S盒,记为 S1, S2, …, S8。
输入: 每个S盒的输入是 6位 数据(b1 b2 b3 b4 b5 b6)。
输出: 每个S盒的输出是 4位 数据。
位置: 在F函数中,与子密钥异或后的48位数据被平均分成8组,每组6位,分别进入对应的S1到S8盒进行处理。
S盒的工作机制(查找表方法)
每个S盒本质上是一个4行16列的固定查找表。6位输入如何在这个表中定位到一个4位输出,是理解S盒的关键。查找步骤:
行列确定:
将6位输入 b1 b2 b3 b4 b5 b6 中的 首位b1和末位b6 组合成一个2位二进制数 (b1
b6)。这个数的十进制值决定了查找的行号(0, 1, 2, 3)。将中间4位 b2 b3 b4 b5 组合成一个4位二进制数。这个数的十进制值决定了查找的列号(0 到 15)。
输出获取:
在对应的S盒表中,找到(行, 列)交叉位置的数字(范围是0-15,即4位二进制数)。
将此数字转换为4位二进制,即为该S盒的输出。
第五步
对S盒获取的输出进行一个P盒(32位)混淆,和IT类似
1 | P盒 |
第六步
此时获得的$R_{i}$和$L_{i}$进行异或运算再得到一个新的$R_{i}$
最后的最后将$R_{i}$和$L_{i}$进行交换得到下一轮的$R_{i}$和$L_{i}$(第16轮就不进行交换了)
最终合并
合并规则:
将最后一轮的输出按 R16 || L16 的顺序合并(即右半部分在前,左半部分在后)。
最后的最后进行末置换
$IP^{-1}$表如下
1 | 40, 8, 48, 16, 56, 24, 64, 32, |
随后得到真正的密文
额外信息:S表
1 | S1 |
解密过程
解密与加密完全相同的算法 (从前到后的顺序一样),只是子密钥使用顺序相反:
加密:K1, K2, …, K16
解密:K16, K15, …, K1
