美国国家标准技术研究所在2001年发布了高级加密标准(AES)。AES是一个对称分组密码算法,旨在取代DES成为普遍使用的标准。git
根据使用的密码长度,AES最多见的有3种方案,用以适应不一样的场景要求,分别是AES-12八、AES-192和AES-256。本文主要对AES-128进行介绍,另外两种的思路基本同样,只是轮数会适当增长。github
AES加解密的流程图以下:算法
AES加密过程涉及到4种操做:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。解密过程分别为对应的逆操做。因为每一步操做都是可逆的,按照相反的顺序进行解密便可恢复明文。加解密中每轮的密钥分别由初始密钥扩展获得。算法中16字节的明文、密文和轮密钥都以一个4x4的矩阵表示。数组
接下来分别对上述5种操做进行介绍。安全
字节代替的主要功能是经过S盒完成一个字节到另一个字节的映射。S盒的详细构造方法能够参考文献[1]。网络
下图(a)为S盒,图(b)为S-1(S盒的逆)。函数
S和S-1分别为16x16的矩阵。假设输入字节的值为a=a7a6a5a4a3a2a1a0,则输出值为S[a7a6a5a4][a3a2a1a0],S-1的变换也同理。编码
例如:字节00替换后的值为(S[0][0]=)63,再经过S-1便可获得替换前的值,(S-1 [6][3]=)00。加密
行移位的功能是实现一个4x4矩阵内部字节之间的置换。spa
正向行移位的原理图以下:
实际移位的操做便是:第一行保存不变,第二行循环左移1个字节,第三行循环左移2个字节,第四行循环左移3个字节。假设矩阵的名字为state,用公式表示以下:state’[i][j] = state[i][(j+i)%4];其中i、j属于[0,3]
逆向行移位便是相反的操做,用公式表示以下:state’[i][j] = state[i][(4+j-i)%4];其中i、j属于[0,3]
列混淆:利用GF(28)域上算术特性的一个代替。
正向列混淆的原理图以下:
根据矩阵的乘法可知,在列混淆的过程当中,每一个字节对应的值只与该列的4个值有关系。此处的乘法和加法都是定义在GF(28)上的,须要注意以下几点:
1) 将某个字节所对应的值乘以2,其结果就是将该值的二进制位左移一位,若是该值的最高位为1(表示该数值不小于128),则还须要将移位后的结果异或00011011;[1]
2) 乘法对加法知足分配率,例如:07·S0,0=(01⊕02⊕04)·S0,0= S0,0⊕(02·S0,0)(04·S0,0)
3) 此处的矩阵乘法与通常意义上矩阵的乘法有所不一样,各个值在相加时使用的是模2加法(至关因而异或运算)。
假设某一列的值以下图,运算过程以下:
同理能够求出另外几个值。
逆向列混淆的原理图以下:
因为:
说明两个矩阵互逆,通过一次逆向列混淆后便可恢复原文。
任何数和自身的异或结果为0。加密过程当中,每轮的输入与轮密钥异或一次;所以,解密时再异或上该轮的密钥便可恢复输入。
密钥扩展的原理图以下:
密钥扩展过程说明:
1) 将初始密钥以列为主,转化为4个32 bits的字,分别记为w[0…3];
2) 按照以下方式,依次求解w[j],其中j是整数而且属于[4,43];
3) 若j%4=0,则w[j]=w[j-4]⊕g(w[j-1]),不然w[j]=w[j-4]⊕w[j-1];
函数g的流程说明:
4) 将w循环左移一个字节;
5) 分别对每一个字节按S盒进行映射;
6) 与32 bits的常量(RC[j/4],0,0,0)进行异或,RC是一个一维数组,其值以下。(RC的值只须要有10个,而此处用了11个,实际上RC[0]在运算中没有用到,增长RC[0]是为了便于程序中用数组表示。因为j的最小取值是4,j/4的最小取值则是1,所以不会产生错误。)
RC = {00, 01, 02, 04, 08, 10, 20, 40, 80, 1B, 36}
在GitHub上找到的AES实现代码,感受写得不错。
https://github.com/dhuertas/AES/blob/master/aes.c
[1] William Stallings著;王张宜等译. 密码编码学与网络安全——原理与实践(第五版)[M]. 北京:电子工业出版社,2011.1.