AES加密算法的InvShiftRows变换
我将为您详细讲解AES(高级加密标准)算法中解密过程的一个关键步骤——InvShiftRows(逆行移位)变换。这是一个相对基础但至关重要的操作,让我们循序渐进地理解它。
1. 题目描述
AES是一种广泛使用的对称分组密码算法。其加解密过程由多个轮(通常为10、12或14轮)组成,每轮包含字节替换(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)四个基本步骤(最后一轮略有不同)。在解密时,需要使用对应的逆步骤来恢复明文。
InvShiftRows变换是ShiftRows变换的逆运算。在加密时,ShiftRows对状态矩阵(State)的每一行进行循环左移位操作,目的是“打散”每一行中字节的列对齐关系,增强算法的扩散性。解密时,InvShiftRows则对每一行进行循环右移位,将字节移回它们原来的列位置,从而撤销加密时的移位效果。理解这个过程,是理解AES加解密对称性的基础。
2. 核心概念:AES的状态(State)
在深入变换之前,我们必须先明确AES处理数据的内部格式。AES的分组长度为128位(16字节)。在算法内部,这16个字节被组织成一个4x4的矩阵,称为“状态”(State)。这个矩阵按列优先顺序填充。
假设我们的128位数据(16字节)为:B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15。
那么,状态矩阵 S 的表示如下:
| S[0,0] | S[0,1] | S[0,2] | S[0,3] | 对应于字节:| B0 | B4 | B8 | B12 |
| S[1,0] | S[1,1] | S[1,2] | S[1,3] | 对应于字节:| B1 | B5 | B9 | B13 |
| S[2,0] | S[2,1] | S[2,2] | S[2,3] | 对应于字节:| B2 | B6 | B10 | B14 |
| S[3,0] | S[3,1] | S[3,2] | S[3,3] | 对应于字节:| B3 | B7 | B11 | B15 |
(S[r,c] 表示第r行、第c列的字节,r和c从0开始计数)。
3. 正变换:ShiftRows(用于加密)
要理解逆变换,必须先清楚它的正向操作。
- 目标:破坏状态矩阵中每一列的字节排列,将不同行的字节分散到不同的列,以实现“行间扩散”。
- 操作规则:
- 第0行:保持不动(循环左移0字节)。
- 第1行:循环左移1字节。即
(S[1,0], S[1,1], S[1,2], S[1,3])变为(S[1,1], S[1,2], S[1,3], S[1,0])。 - 第2行:循环左移2字节。即
(S[2,0], S[2,1], S[2,2], S[2,3])变为(S[2,2], S[2,3], S[2,0], S[2,1])。 - 第3行:循环左移3字节。即
(S[3,0], S[3,1], S[3,2], S[3,3])变为(S[3,3], S[3,0], S[3,1], S[3,2])。
举例:
假设加密前某一轮的状态矩阵为:
| a00 | a01 | a02 | a03 |
| a10 | a11 | a12 | a13 |
| a20 | a21 | a22 | a23 |
| a30 | a31 | a32 | a33 |
经过ShiftRows变换后,变为:
| a00 | a01 | a02 | a03 | // 第0行不变
| a11 | a12 | a13 | a10 | // 第1行左移1位
| a22 | a23 | a20 | a21 | // 第2行左移2位
| a33 | a30 | a31 | a32 | // 第3行左移3位
4. 逆变换:InvShiftRows(用于解密)
InvShiftRows是ShiftRows的逆操作,目标是将被ShiftRows打乱的字节顺序恢复回原始状态。
- 核心逻辑:对每一行进行循环右移位,且移位次数与ShiftRows的循环左移次数完全对应。
- 操作规则:
- 第0行:保持不动(循环右移0字节)。
- 第1行:循环右移1字节。即
(S[1,0]', S[1,1]', S[1,2]', S[1,3]')变为(S[1,3]', S[1,0]', S[1,1]', S[1,2]')。这正好是第1行左移1位的逆操作。 - 第2行:循环右移2字节。即
(S[2,0]', S[2,1]', S[2,2]', S[2,3]')变为(S[2,2]', S[2,3]', S[2,0]', S[2,1]')。注意,对于第2行,循环右移2位等同于循环左移2位,但概念上我们仍称之为右移。 - 第3行:循环右移3字节。即
(S[3,0]', S[3,1]', S[3,2]', S[3,3]')变为(S[3,1]', S[3,2]', S[3,3]', S[3,0]')。这正好是第3行左移3位的逆操作。
举例延续:
假设解密时,某一轮输入InvShiftRows的状态矩阵是上面加密输出后的那个矩阵(我们用 b 表示):
| b00 | b01 | b02 | b03 | // 即 | a00 | a01 | a02 | a03 |
| b10 | b11 | b12 | b13 | // 即 | a11 | a12 | a13 | a10 |
| b20 | b21 | b22 | b23 | // 即 | a22 | a23 | a20 | a21 |
| b30 | b31 | b32 | b33 | // 即 | a33 | a30 | a31 | a32 |
经过InvShiftRows变换后:
- 第0行
(b00, b01, b02, b03)保持为(a00, a01, a02, a03)。 - 第1行
(b10, b11, b12, b13)循环右移1位:(a13, a10, a11, a12)? 等等,这里要小心核对。输入是(a11, a12, a13, a10)。循环右移1位意味着最右边的字节a10移到最左边,结果是(a10, a11, a12, a13)。成功恢复! - 第2行
(b20, b21, b22, b23)循环右移2位:输入是(a22, a23, a20, a21)。循环右移2位后,变为(a20, a21, a22, a23)。成功恢复! - 第3行
(b30, b31, b32, b33)循环右移3位:输入是(a33, a30, a31, a32)。循环右移3位后,变为(a30, a31, a32, a33)。成功恢复!
变换后的矩阵完全恢复到了加密前ShiftRows操作前的状态。
5. 算法意义与在解密流程中的位置
InvShiftRows是AES解密轮函数(InvCipher)的组成部分。在完整的一轮解密中,步骤通常为(以标准AES-128的轮解密为例):
- InvShiftRows:将字节移回正确的列位置。
- InvSubBytes:对每个字节进行逆S盒代换,恢复S盒变换。
- AddRoundKey:与轮密钥进行异或(XOR)。注意,由于AddRoundKey是其自身的逆,所以它在加解密中形式相同。
- InvMixColumns:对每一列进行逆列混淆变换,恢复列混淆变换。
在解密的第一轮之前,会有一个初始的AddRoundKey(使用最后一轮轮密钥)。解密的最后一轮省略了InvMixColumns步骤,以对应加密时第一轮前有AddRoundKey且最后一轮省略MixColumns。
总结:
InvShiftRows是一个简单而优雅的线性变换。它不进行任何复杂的数学运算,仅通过对状态矩阵各行进行不同偏移量的循环右移,就完美地逆转了加密过程中ShiftRows的扩散效果。这个步骤体现了AES设计中“可逆性”和“对称性”的精巧构思,是连接加密与解密过程的关键环节,确保了在拥有正确密钥的情况下,密文能够被准确地还原为原始明文。