测试输出结果:

2)加密
根据 AES 加密的整体流程图(本文开头),伪代码如下:
从伪代码描述中可以看出,AES 加密时涉及到的子程序有SubBytes()、ShiftRows()、MixColumns()和AddRoundKey()。下面我们一个一个进行介绍:
① S盒变换-SubBytes()
在密钥扩展部分已经讲过了,S盒是一个 16 行 16 列的表,表中每个元素都是一个字节。S盒变换很简单:函数SubBytes()接受一个 4x4 的字节矩阵作为输入,对其中的每个字节,前四位组成十六进制数 x 作为行号,后四位组成的十六进制数 y 作为列号,查找表中对应的值替换原来位置上的字节。
② 行变换-ShiftRows()
行变换也很简单,它仅仅是将矩阵的每一行以字节为单位循环移位:第一行不变,第二行左移一位,第三行左移两位,第四行左移三位。如下图所示:

③ 列变换-MixColumns()
函数MixColumns()同样接受一个 4x4 的字节矩阵作为输入,并对矩阵进行逐列变换,变换方式如下:

注意公式中用到的乘法是伽罗华域(GF,有限域)上的乘法,高级加密标准文档 fips-197 上有讲,如果还是不懂,请自行Google。

④ 与扩展密钥的异或-AddRoundKey()
扩展密钥只参与了这一步。根据当前加密的轮数,用w[]中的 4 个扩展密钥与矩阵的 4 个列进行按位异或。如下图:
好了,到这里 AES 加密的各个部分就讲完了。算法实现的 C++ 源码在文章后面第三部分。
3)解密
根据 AES 解密的整体流程图(本文开头),伪代码如下:
从伪代码可以看出,我们需要分别实现 S 盒变换、行变换和列变换的逆变换InvShiftRows()、InvSubBytes()和InvMixColumns()。下面就简单的讲一下这三个逆变换:










