AES加密算法的解密过程(逆向变换顺序与等价解密密钥计算)
好的,我们来看一个AES算法中常被误解的核心问题:它的标准解密流程。许多人知道AES加解密是对称的,但具体步骤的顺序和内容容易混淆。今天我们重点讲解,在已知所有轮密钥(\(K_0\) 到 \(K_{Nr}\))后,如何对一个已加密的密文块(128位)进行标准解密,恢复到原始明文。这个过程关键在于理解解密是加密的逆过程,且逆变换需要按特定顺序执行。
题目背景
AES(高级加密标准)是一种迭代型分组密码,支持128、192、256位三种密钥长度。其加密过程包括多轮重复的四个基本步骤(字节替换 SubBytes、行移位 ShiftRows、列混合 MixColumns、轮密钥加 AddRoundKey),但首尾轮稍有不同。解密过程必须严格反向执行这些步骤的逆操作,并且轮密钥的使用顺序也相反。
解题过程
我们假设读者已熟悉AES的加密流程和基本变换。这里以 AES-128 为例(10轮加密,共11个轮密钥 \(K_0, K_1, ..., K_{10}\)),讲解如何解密密文 \(C\) 得到明文 \(P\)。
第一步:明确标准解密流程的框架
标准解密(或称“逆密码”)的执行顺序,与加密顺序完全相反,且每一步都使用对应的逆变换(InvSubBytes, InvShiftRows, InvMixColumns),但 AddRoundKey 的逆就是其自身(因为 XOR 的逆仍是 XOR)。
解密流程框架如下:
- 初始轮: 对密文 \(C\) 执行
AddRoundKey(K10)。 // 使用最后一轮加密的轮密钥 - 主循环(9轮,i 从 9 递减到 1): 每轮依次执行:
InvShiftRowsInvSubBytesAddRoundKey(Ki)InvMixColumns
- 最终轮(第10轮解密):
InvShiftRowsInvSubBytesAddRoundKey(K0)// 使用初始轮密钥(即白化密钥)
这个顺序是加密的镜像逆序:注意加密的最后一轮没有 MixColumns,所以解密的第一轮(对应加密的最后一轮)自然没有 InvMixColumns;加密的第一轮(初始轮)只有 AddRoundKey,所以解密的最后一轮也只有 AddRoundKey。
第二步:深入理解为何是这个顺序
我们对比加密一轮(非最终轮)和解密对应的逆一轮(非初始解密轮):
- 加密(正向)顺序:
SubBytes→ShiftRows→MixColumns→AddRoundKey(Ki) - 解密(逆向)顺序:
AddRoundKey(Ki)的逆(还是它自身)应该在最先执行,以“抵消”加密时最后加的密钥。但直接这样做会打乱状态。实际上,因为 AddRoundKey 与 MixColumns 是线性操作(可交换顺序,但有代价),而 SubBytes 是非线性的,所以逆操作必须按特定顺序。
一个关键等式揭示了等价关系:
InvMixColumns( AddRoundKey(Ki) ) = AddRoundKey( InvMixColumns(Ki) )
这里 InvMixColumns(Ki) 意味着对轮密钥的每一列(4字节)单独应用 InvMixColumns 变换。这使得我们可以将解密流程变换顺序,形成一种与加密结构更相似的“等价解密密钥”流程。
第三步:计算“等价解密轮密钥”
为了方便硬件/软件实现,AES标准提供了一种优化解密方案:通过预处理轮密钥,使解密流程(除首尾轮外)与加密流程的顺序一致(即先 InvSubBytes, 再 InvShiftRows, 再 AddRoundKey, 最后 InvMixColumns),但需要使用“等价解密轮密钥”。
具体计算方法如下:
- 初始解密轮密钥: \(DK_{10} = K_{10}\) (直接使用)
- 前9轮解密轮密钥(i 从 9 到 1):
\[ DK_i = \text{InvMixColumns}(K_i) \]
即将加密过程的轮密钥 $K_i$(对于 $i=1$ 到 $9$)的每一列(4个字节)通过 `InvMixColumns` 变换得到新的轮密钥 $DK_i$。
- 最终解密轮密钥: \(DK_0 = K_0\)
这样处理后的 \(DK_{10}, DK_9, ..., DK_0\) 就是一套专门用于优化解密流程的密钥。
第四步:使用等价解密密钥的执行流程
使用计算好的 \(DK\) 序列,解密流程可以调整为与加密同构的顺序,更容易在硬件上复用加密数据路径:
- 初始轮:
AddRoundKey(DK10)// 注意 DK10 = K10 - 主循环(9轮,i 从 9 递减到 1): 每轮依次执行:
InvSubBytesInvShiftRowsInvMixColumnsAddRoundKey(DKi)// 注意 DKi 已经预先经过 InvMixColumns 处理
- 最终轮:
InvSubBytesInvShiftRowsAddRoundKey(DK0)// DK0 = K0
请注意:此流程中 InvMixColumns 和 AddRoundKey(DKi) 的顺序,与标准加密流程(MixColumns → AddRoundKey(Ki))是一致的。这正是通过预先处理密钥实现的“等价性”。
第五步:逐步演算示例(概念性)
假设我们有:
- 密文 \(C\) (16字节)。
- 加密轮密钥 \(K_0, K_1, ..., K_{10}\) 已通过密钥扩展算法得到。
计算步骤:
-
预处理解密轮密钥:
- 保留 \(DK_{10} = K_{10}\), \(DK_0 = K_0\)。
- 对 \(i = 9, 8, ..., 1\),计算 \(DK_i = \text{InvMixColumns}(K_i)\)。具体是对 \(K_i\) 的每个4字节列,乘以 InvMixColumns 的固定矩阵(在GF(2^8)上)。
-
解密状态初始化:
State = C
-
执行解密轮函数:
- 初始轮:
State = State ⊕ DK10。 - 循环9轮(i 从 9 到 1):
a.InvSubBytes(State): 通过逆S盒(一个固定的查找表)替换每个字节。
b.InvShiftRows(State): 对状态矩阵的第1、2、3行分别循环右移 0、1、2、3 字节(注意加密是左移)。
c.InvMixColumns(State): 对每一列乘以固定的逆矩阵。
d.AddRoundKey(State, DKi)。 - 最终轮:
a.InvSubBytes(State)
b.InvShiftRows(State)
c.AddRoundKey(State, DK0)
- 初始轮:
-
输出: 此时的
State就是原始明文 \(P\)。
第六步:验证与总结
这个过程的正确性,核心依赖于 InvMixColumns 与 AddRoundKey 的线性可交换性,以及所有变换的逆运算存在且唯一。通过将逆变换按此顺序执行,或使用预处理后的等价密钥调整顺序,我们都能确保:
\[\text{Decrypt}(\text{Encrypt}(P)) = P \]
关键点总结:
- 标准解密: 严格按加密的逆序执行逆变换。
- 等价解密密钥: 为优化实现,可预先对加密轮密钥(除首尾)应用
InvMixColumns变换,得到解密轮密钥 \(DK_i\)。 - 使用 \(DK_i\) 的解密流程: 与加密流程顺序一致(SubBytes → ShiftRows → MixColumns → AddRoundKey),易于硬件复用。
- 最终结果: 两种方法本质等价,都能正确恢复明文。
理解这个流程,不仅能掌握AES解密,更能深入体会分组密码中线性与非线性操作交织、顺序与等价变换的设计艺术。