本文转载自:《现代密码学》课程笔记知乎专栏
仅作个人学习记录。
上一次讲了分组密码的基本概念和DES。
总结如下:

图5-1 上一讲总结
一、AES的整体结构及简介:
1.AES简介:
AES即高级加密标准(Advanced Encryption Standard),是美国NIST在2001年发布的,旨在代替DES称为广泛使用的标准。AES是一种对称分组密码算法。
2.AES的分组长度和密钥长度:
AES的明文分组长度为128位(16字节),密钥长度可以为128位(16字节)、192位(24字节)、256位(32字节),根据密钥长度的不同,AES分为AES-128、AES-192、AES-256三种。
3.AES的整体结构:
AES加密体制也是由多轮加密构成,除了结尾的一轮,其他轮都是由四个步骤组成——字节代替、行移位、列混淆、轮密钥加。而最后一轮仅包括字节代替、行移位、轮密钥加这三步。AES迭代的轮数与密钥的长度相关,16字节的密钥对应着迭代10轮,24字节的密钥对应着迭代12轮,32字节的密钥对应着迭代14轮。在开始所有轮迭代之前,需要进行一次初始变换——一次轮密钥加,这一步往往被称为第0轮。
图5-2和图5-3是对AES结构的简单描述:

图5-2 AES加密过程
我们知道DES的加解密结构是完全相同的,但是AES的加解密结构却不同,这是因为AES没有采用Feistel密码体制。但是AES每一个步骤都是可逆的,因此只要把AES加密中的每一步换成其逆变换,即可得到AES解密算法。值得注意的是,解密算法也是先进行第0轮,而且最后一轮也是只有三步。在解密算法中,需要倒着顺序使用轮密钥。

图5-3 AES加密和解密过程(详细)
二、AES的迭代函数:
上一部分提到,AES需要依次执行十几次迭代。这一部分,我们来讲一讲每一轮迭代四个步骤:字节代替、行移位、列混淆、轮密钥加的细节。
与DES不同,AES的每一步都有其设计的具体原理,我们在这里也会详细讲解。
1.字节代替(作用为混淆):
(1)实现方法:
字节代替就是一个简单的查表操作。具体做法就是对明文的每一个字节使用S盒进行查表代替(AES明文共16字节,128位)。
S盒如下图所示:

图5-4 AES的S盒
明文的一个字节由8位组成,以这8位的高4位作为S盒表的行值,低4位作为S盒表的列值。在其中寻找对应的代替结果。例如:十六进制数{3F}表示代替结果在第三行,第F列,因此结果为{75}。
同样,在执行解密过程时,需要经过逆字节代替,因此也有相应的逆S盒,其代替方法与S盒完全相同。逆S盒与S盒是互逆的。
逆S盒如下图所示:

图5-5 AES的逆S盒
(2)设计原理:
以下讲解S盒是怎么被设计成这个样子的:
- 首先,对16x16格的S盒进行升序初始化:按照行列值,一直从{00},递增初始化到{FF}。比如:第一行:{00},{01},{02},{03}……{0F};第二行:{10},{11}……{1F}。
- 经过初始化后,分别用S盒每一格的乘法逆元(
中的)代替原来格子中的内容,{00}仍然用{00}代替。 - S盒的每一格均为8位,把这8位分别记为
。之后,分别对S盒的每一格进行如下变换:

图5-6 S盒的构造
其中,
用矩阵表示为

图5-7 矩阵表示
这里的矩阵乘法与线性代数中的完全相同,只是乘或加之后需要
这个矩阵变换可以被表示为
2.行移位(作用为扩散):
实现方法非常的简单。AES的明文分组长度为128位,共16个字节。首先将这16个字节按顺序排成一个

图5-8 行移位举例
逆向行移位的实现方式与正向相同,只是改成了循环右移。
3.列混合(作用为扩散):
首先,把16字节的待加密明文以字节为单位按顺序排列成
其中
这个过程也可以写为矩阵形式:
让待加密的
如下图所示:等号左边,右侧的矩阵为待列混合的字节方阵,左侧为相乘的矩阵,等号右侧为结果。这个过程也可以拿矩阵下面的等式来表示。

图5-9 列混合矩阵形式
逆向列混合对应的矩阵变换为:

图5-10 逆向列混合
显然,可以证得,这两个矩阵是互逆的:

图5-11 两矩阵互逆
4.轮密钥加:
轮密钥是原来的密钥经过密钥编排算法得到的一个密钥,其长度与明文分组长度相同——16字节、128位,AES中,每一轮迭代的轮密钥都互不相同,之后会详细讲解密钥编排算法。
所谓轮密钥加,就是简单地将待加密的内容与轮密钥按位异或。也可以视为字节之间的操作,如下图所示:左边是待加密的内容,右边是轮密钥,等号右边为结果。

图5-12 轮密钥加举例
轮密钥加的逆变换与正向变换相同,即密文再次与轮密钥进行按位异或即得到原来的内容。
三、AES的密钥编排算法
AES的密钥长度可以为16字节,24字节或者32字节,根据密钥长度的不同,AES分为AES-128、AES-192、AES-256三种。这里常以字(word)为单位来衡量密钥长度,
AES的密钥编排算法包含密钥扩展和轮密钥选取两部分。密钥扩展用来将原来的4字、6字或者8字密钥扩展成拥有一定字数的长密钥;轮密钥选取用来从长密钥中选取若干部分,使其充当AES每一轮迭代的轮密钥。
1.密钥扩展算法:
(1)为什么需要密钥扩展:
不论密钥长度为多少,我们的明文分组始终为16字节(4字)。上文提到,在轮密钥加部分,我们需要为每一轮提供一个长度为4字的轮密钥。
对于AES-128(4字密钥),需要迭代10轮,加上第0轮,共需要进行11次轮密钥加,而每一次轮密钥加都需要一个长度为4字的轮密钥,因此所需要的扩展密钥长度为
对于AES-192(6字密钥),需要迭代12轮,加上第0轮,共需要进行13次轮密钥加,所需要的扩展密钥长度为
对于AES-256(8字密钥),需要迭代14轮,加上第0轮,共需要进行15次轮密钥加,所需要的扩展密钥长度为
因此我们需要一定的方法用来将密钥扩展到一定的长度。
(2)AES-128的密钥扩展方法:
在这个算法中,输入的原密钥长度为16字节(byte),保存在数组key[16]中,输出为长为44字(word)的扩展密钥,保存在数组w[44]中。
其扩展算法可用下面的伪代码描述:
1 | //只是伪代码,不能运行 |
- 第一个for循环:首先直接把输入密钥的4个字复制到扩展密钥的前4个字上。
- 第二个for循环:对扩展密钥的后40个字进行处理,处理的步骤如下:
(a).使用temp变量保存前一个字的内容
(b).如果当前密钥字的编号(从0开始数)能够整除4,就对temp先后进行字循环(RotWord),字代替(SubWord)两个变换,之后再进行轮常量异或(这三步一般统称为函数g)。如果当前密钥字的编号(从0开始数)不能够整除4,则跳过这一步,直接进入步骤f。
(c).字循环(RotWord):将一个字中四个字节的内容循环左移一个字节。即使得
(d).字代替(SubWord):使用前面提到的S盒(图5-4)对一个字中的每一个字节进行代替。
(e).轮常量异或:经过步骤c、d后,所得的结果再与轮常量Rcon[i/4]进行按位异或,即得到最终的temp。这里的

图5-13 10个轮常量
(f).使用4个字之前的字与temp(如果没有经过处理,则为上一个字)进行异或,即得到当前字。
总结规律,我们可以看出,除了第0轮的轮密钥,其他轮的当前字都是由前一个字(可能经过函数g处理,也可能没经过)与4个字之前的字进行异或得到。此外,每一个轮密钥的最后一个字总要经过函数g(字循环、字代替、轮常量异或)的作用。

图5-14 密钥扩展算法的简明表示
(2)AES-192的密钥扩展方法:
AES-192的密钥有6个字,其密钥扩展方法与AES-128完全类似。第一个for循环的填充变成了6个字;之后的判断整除条件变为了能否整除6。
1 | //只是伪代码,不能运行 |
(3)AES-256的密钥扩展方法:
AES-256的密钥长度为8字。其密钥扩展与AES-128也基本相同,只是修改了填充的字数,值得注意的是:AES-256在第二个for循环里添加了判断条件,当i%==4时,要对temp进行一次字代替。
1 | //只是伪代码,不能运行 |
2.轮密钥选取算法:
经过密钥扩展算法,我们得到了一长串扩展密钥,现在需要将扩展密钥分为一系列的轮密钥,从而应用到轮密钥加步骤中。
选取方法就是简单地按先后顺序选取,依次充当各轮的轮密钥,如下图所示:

图5-15 AES-128轮密钥选取

图5-16 AES-192轮密钥选取

图5-17 AES-256轮密钥选取
这就是AES的全部内容。