高级加密标准(AES,Advanced Encryption Standard)是最常见的对称加密算法,被很多游戏在进行加密传输的时候采用,所谓对称加密也就是加密和解密用相同的密钥。我在大二的时候,学过一门叫《密码学原理》的课,但当时对 AES 加密算法只是做了简单的介绍,没有深入讲解其原理,现在我决定来重新学习一下。
一、AES 的基本结构
因为 AES 为分组密码,即把明文分为长度相等的不同组,每次加密一组数据。在 AES 中,分组长度只能是128位,即16个字节。密钥长度则可以是128位、192位或256位,根据密钥的长度,加密轮数也有所不同(比如 AES-128,密钥长度32位,分组长度32位,加密轮数10轮),下面简单讲解 AES-128。
AES 在加密一组明文的时候,会执行10次轮函数,这个轮函数前9次操作是一样的,只有第10次有所不同,而 AES 的核心即为这个轮函数。
AES 处理的单位是字节,128位明文分组 P 和 密钥 K 都被分成16个字节,分别记为 P = P0 P1 ... P1 和 K = K0 K1 ... K15。明文分组一般用字节为单位的正方形矩阵描述,称为状态矩阵:
假设明文分组 P = abcdefghijklmnop,则状态矩阵为:
同理,128位密钥也可以这么表示,矩阵的每一列为1个32位比特字,通过密钥编排函数该密钥矩阵被扩展成一个44个字组成的序列 W[0] W[1] ... W[43],该序列的前4个元素 W[0] W[1] W[2] W[3] 是原始密钥,用于加密运算中的初始密钥加;后面40个字分为10组,每组4个字(128比特)分别用于10轮加密运算中的轮密钥加:
二、AES 加解密过程
加解密互相是对方的逆操作。图上 W[0, 3] 是指 W[0] W[1] W[2] W[3] 串联组成的128位密钥。加密的第1轮到第9轮的轮函数一样,包括4个操作:字节代换、行位移、列混合和轮密钥加。最后一轮迭代不执行列混合。另外,在第一轮迭代之前,先将明文和原始密钥进行一次异或加密操作。
三、字节代换
AES 的字节代换是一个简单的查表工作。AES 定义了一个 S 盒和一个逆 S 盒。状态矩阵中的每一个元素(含1个字节)将字节高4位作为行值,低4位作为列值,取 S 盒中的元素作为输出。而字节代换逆操作也就是查逆 S 盒来变换。
四、行移位
AES 的行移位也是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节:
而行移位的逆操作则是进行相反的移位操作。
五、列混合
列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵(注意:其运算中涉及的加法和乘法都是定义在 GF(2^8)上的加法和乘法,目的就是为了确保运算结果不会溢出定义域):
六、轮密钥加
轮密钥加是将128位轮密钥 Ki 同状态矩阵中的数据进行逐位异或操作。如下图,可以看成S0 S1 S2 S3 组成的32位字与W[4i]的异或运算:
轮密钥加的逆运算同正向的轮密钥加运算完全一致,这是因为异或的逆操作是其自身。轮密钥加非常简单,但却能够影响S数组中的每一位。
七、密钥扩展
AES 密钥扩展算法的输入值是4个字(16字节),输出值是一个由44个字组成(176字节)的一维线性数组,轮常量取不同值就是为了消除不同轮密钥产生方式上的对称性或相似性。以下伪码描述了这个扩展:
KeyExpansion(byte key[16], word w[44]){
word temp
for(i=0; i<4; i++) //将输入的密钥直接复制到扩展密钥数组的前四个字
w[i]=word(key[4*i],key[4*i+1],key[4*i+2],key[4*i+3]);
temp = w[i-1];
if(i mod 4 == 0) //对w数组下标为4的倍数的元素采用更复杂的函数来计算
temp = SubWord(RotWord(temp))⊕Rcon[i/4];
w[i] = w[i-4] + temp; //每一个新增的字w[i]依赖于w[i-1] 和w[i-4]
}
RotWord的功能是字循环,即使一个字的4个字节循环左移1个字节。
SubWord是利用S盒对输入字的每个字节进行字节代替。
Rcon[i]是轮常量,代表一个字,这个字最右边三个字节总是0,因此字与Rcon异或,其结果只是与该字最左边的那个字节相异或。每一轮的轮常量都不相同,其定义为
Rcon[i] = (RC[i],0,0,0),其中RC[1] = 1,RC[i] = 2•RC[i-1]乘法是定义在域GF(28)上的。
RC[i]的值按照十六进制表示为