AES(高级加密标准)是一种分组密码,它把明文分成固定长度的块(128位,即16字节),然后通过多轮复杂的变换,把每一块加密成密文。AES的轮数取决于密钥长度:128位密钥需要10轮,192位需要12轮,256位需要14轮。每一轮(除了最后一轮)都包含四个步骤:字节替换、行移位、列混合、轮密钥加。最后一轮省略列混合。
这四步操作像一台精密的机器,把数据反复“搅拌”,直到无法辨认出任何原始特征。下面我们用图解的方式,一步步拆解AES的加密过程。
AES的状态矩阵
在加密开始前,128位的明文被排列成一个4×4的矩阵,每个元素是一个字节(8位)。这个矩阵称为状态矩阵(State)。例如,明文的前4个字节放在第一列,接着4个字节放在第二列,以此类推:
+----+----+----+----+ |
注意:AES是按列填充的,这一点和通常的按行阅读不同,但理解这一点对后面的行移位很重要。
第一步:字节替换(SubBytes)
作用:对每个字节独立进行非线性替换,增加混淆性。
AES有一个固定的替换表,称为S盒(S-box)。它是一个16×16的表格,每个字节的高4位作为行索引,低4位作为列索引,从表中取出一个新的字节。例如,输入字节为0x53,高4位是5,低4位是3,查表得到0xED。
S盒的设计非常巧妙,它具备非线性特性,并且能抵抗差分密码分析和线性密码分析。更重要的是,S盒是可逆的——解密时使用逆S盒。
图解:可以把状态矩阵的每个格子都看作一个小盒子,里面装着一个字节。字节替换就是用S盒把每个盒子里的内容换成另一个字节。
原始矩阵 S盒变换后 |
第二步:行移位(ShiftRows)
作用:对矩阵的每一行进行循环左移,打乱字节的顺序,实现扩散。
规则如下:
- 第0行(第一行)不移位。
- 第1行向左循环移1个字节。
- 第2行向左循环移2个字节。
- 第3行向左循环移3个字节。
用矩阵表示更加直观。假设经过字节替换后的状态矩阵为:
b0 b4 b8 b12 |
行移位后变为:
b0 b4 b8 b12 ← 第0行不变 |
这个操作的目的是让每一列的数据分散到不同列中,为下一步的列混合做准备。
第三步:列混合(MixColumns)
作用:对每一列的四个字节进行线性变换,进一步混合数据。
列混合是把每一列看作一个多项式,并与一个固定多项式相乘,然后取模。但在实际实现中,它是通过矩阵乘法完成的。对于每一列,将四个字节视为一个向量,左乘一个固定的4×4矩阵(在GF(2⁸)有限域中):
[ s0'] [ 2 3 1 1 ] [ s0 ] |
这里的乘法和加法都是在有限域GF(2⁸)中定义的,不是普通的整数运算。有限域运算听起来复杂,但硬件实现时可以用查表完成,软件上也有快速算法。
直观理解:列混合就像把一列里的四个字节搅在一起,每个输出字节都依赖于输入列的所有四个字节。经过这一步,矩阵的扩散性大大增强——改变任何一个字节,都会影响到整列的所有字节。
例如,对于第一列(b0, b5, b10, b15),经过列混合后得到新的四个字节(c0, c5, c10, c15)。其他列类似。
图解:把列混合想象成一个搅拌机,每一列的四个字节进去,出来四个新字节,每个新字节都是由原来的四个字节混合而成。
第四步:轮密钥加(AddRoundKey)
作用:将状态矩阵与当前轮的轮密钥进行异或(XOR)。
轮密钥是由初始密钥通过密钥扩展算法生成的,每一轮使用不同的128位轮密钥。轮密钥也排列成4×4的矩阵,与状态矩阵逐字节异或。
异或是简单的比特运算:两个比特相同得0,不同得1。这一步是给状态矩阵加上“密钥的味道”。
一轮完整的AES加密(图解)
我们可以用一张流程图概括一轮AES加密的四个步骤:
┌─────────────────┐ |
对于128位密钥,这样的过程重复10轮,但最后一轮不执行列混合。初始状态在加密开始前会先与初始轮密钥进行一次异或(称为初始轮密钥加)。
一个具体例子(简化)
假设我们有一个极简的状态矩阵(仅用于演示,实际AES的每个字节是8位,这里用数字代替):
原始矩阵:[ 1, 2, 3, 4 ]
[ 5, 6, 7, 8 ]
[ 9,10,11,12]
[13,14,15,16]
字节替换:每个数字按S盒(假设)替换成另一个数字(实际S盒不是简单的线性关系):
[ 11, 22, 33, 44 ]
[ 55, 66, 77, 88 ]
[ 99, 10, 11, 12 ]
[ 13, 14, 15, 16 ]行移位:
- 第0行不变:
[11,22,33,44] - 第1行左移1位:
[66,77,88,55] - 第2行左移2位:
[11,12,99,10] - 第3行左移3位:
[16,13,14,15]
得到:[11,22,33,44]
[66,77,88,55]
[11,12,99,10]
[16,13,14,15]
- 第0行不变:
列混合:对每一列进行矩阵乘(这里仅示意结果,实际计算复杂):
假设第一列(11,66,11,16)变换后得到(23,45,67,89)。其他列类似。轮密钥加:与轮密钥异或,得到最终的状态矩阵。
这个过程反复进行,直到最后一轮。
为什么AES安全?
AES的安全性来自三个层面的设计:
- 混淆:字节替换引入了非线性,使得明文和密文之间的关系极其复杂,无法用简单的线性方程描述。
- 扩散:行移位和列混合让每一个明文字节的影响迅速扩散到整个密文块——改变一个明文字节,大约一半的密文字节会发生变化(这被称为“雪崩效应”)。
- 密钥的参与:每一轮都加入不同的轮密钥,使得即使知道算法,没有密钥也无法还原。
经过10轮这样的搅拌,密文已经完全失去了明文的任何统计特征。时至今日,除了暴力穷举(256位AES的密钥空间大到无法实现),还没有任何有效的方法能攻破AES。
下一节,我们将讨论如何把AES应用到实际中——当数据长度超过128位时,我们需要选择一种工作模式。