一、AES与Rijndael结构的关系
首先需要说明,AES加密属于Rijndael结构,在Rijndael结构中密钥和分组都可以为128,192,256这三中长度,但是AES中规定使用分组为128比特,密钥三种可选 。
(本人在学密码学时便误以为AES的分组也有三种长度,实则不然)
二、分组与状态
既然是分组密码,那么怎么分组呢?
在Rijndael结构中使用状态来表示,状态为一个列优先存储 的矩阵,矩阵中每个元素为8比特组成的字节,该矩阵每列4个元素,有几列取决于分组长度,列数等于分组的字节数除以4,如下以AES为例表示状态矩阵
这里我们记状态矩阵的列数为Nb
同样密钥也使用状态表示,排列和分组矩阵规则相同,记密钥状态的列数为Nk

Rijndael结构中的几个重要函数
1.字节代换
字节代换分两步,
- 第一步:将状态矩阵中的每一个元素看作是GF(2^8)域中的元素,之后求其逆元,如果元素的值为0没有逆元则将其变换为0(即不变)
- 第二步:使用第一步的状态,在其基础上对每一个元素的各比特作为一个向量,将该向量进行一个矩阵的仿射变换为新的向量即可

为了加速算法执行,可以预先构建S盒将以上的状态中每一个元素会通过字节代换到什么结果,直接使用S盒查表即可

解密时需要进行逆字节代换,对于其逆操作为对各元素先进行逆仿射变换后求其逆元,当然为了加速,可以直接使用S盒查表逆向回去
2.行移位
具体各行移位量如下,对于AES,Nb=4,状态矩阵中第一行不变,第i行中各元素循环左移i个字节


逆行移位直接进行逆移位即可
3.列混合
将状态矩阵中各列左乘一个4*4方阵得到的列向量填会状态矩阵中对应列

对于逆列混合,将状态矩阵各行左侧先前加密时左乘矩阵的逆矩阵即可
4.轮密钥加
直接将状态矩阵和密钥矩阵依比特异或即可
根据异或的性质,解密时直接异或即可抵消加密时进行的异或
三、加解密流程图
先介绍Nr即迭代轮数选取规则如下:

加解密流程图如下:

四、密钥拓展




对于轮密钥的选取,第一轮取原始的没经过密钥拓展的密钥,之后依次按照分组长度取出相应长度的轮密钥即可
五、解密优化
在先前解密的流程图中是最容易理解的但是还不够好
为说明原因,这里先给出两个引理
1.字节代换和行移位可互换
这个很好理解,因为先对各原始代换后移动位置和移动位置后进行代换结果是一样的

2.(列混合后与key密钥加)这个操作的逆为(逆列混合后与invKey密钥加)

可使用分配律可证明引理二

到这里便可以发现,解密时可将相邻的字节代换和行移位交换顺序,使用逆列混合的轮密钥即可让列混合和轮密钥加交换顺序。
这就可以解释为什么先前的解密结构不够好,因为它不能复用加密的结构,而使用这两个引理,只要计算InvKey即可实现复用加密的结构。
这不仅对于编程实现和硬件实现都提供了极大的便利,这就是为什么AES指令集中提供了aesimc指令用于对密钥进行逆列混合
六、参考
清华大学出版设的现代密码学第五版及其PPT
最后如果对AES指令集感兴趣可以看我先前的文章,关于如何使用AES指令集实现AES解密