AES的加密公式为C = E(K,P),在加密函数E中,会执行一个轮函数,并且执行10次这个轮函数,这个轮函数的前9次执行的操作是一样的,只有第10次有所不同。也就是说,一个明文分组会被加密10轮。AES的核心就是实现一轮中的所有操作。
AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同,如下表所示:
这里实现的是AES-128,也就是密钥的长度为128位,加密轮数为10轮。
一个明文块16k 转变成 4 X 4(16进制)的矩阵,与子密钥生成的初始矩阵4 X 4(16进制),做一个异或。
由于后续要做10轮加密操作,每轮都要使用一个4X4的矩阵。那么单单一个子密钥生成的4X4的矩阵自然是不够的,所以需要对密钥做扩展。也就是把4X4字节的子密钥 ——> 4X43轮密钥,从4列扩展为44列(这里需要注意的是: 初始变换已经用了第0列到第三列,所以10轮加密从第4列开始取)
比如第i轮(i ∈ [1,10])加密,使用第4i到 4i + 3列的数据作为子密钥矩阵。第1轮,使用第4列,到第4 + 3列,最后一轮使用第40列,到43列作为密钥矩阵。
生成规则
假设i是我们要生成的扩展子密钥列数,如果 i 为四的倍数,那么该列:Wi = Wi-4 ⊕ T(Wi-1)
其中T函数表示三个操作:
将Wi-1列赋值到 Wi上,列[b0, b1, b2 ,b3]更改为 [b1 , b2 , b3 , b0](注意,这里是列,应该是竖起来的,我这里为了方便所以是横的)
使用S盒代换,与下面的S_Box一致
与同轮(第一轮和常量矩阵第一列 第二轮和常量矩阵第二列),给定的矩阵进行同列⊕。可以看出每列对应的i为:4 8 12 16 20 24 28 32 36 40
把输入和对应轮数的子密钥进行异或操作。
矩阵中的各字节通过一定的变换与S_BOX 中的对应元素进行替换。
AES的字节代换其实就是一个简单的查表操作。AES定义了一个S盒和一个逆S盒。
AES的S盒:
状态矩阵中的元素按照下面的方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,取出S盒或者逆S盒中对应的行的元素作为输出。例如,加密时,输出的字节S1为0x12,则查S盒的第0x01行和0x02列,得到值0xc9,然后替换S1原有的0x12为0xc9。
逆字节代换也就是查逆S盒来变换,逆S盒如下:
将矩阵按如下规则进行移位操作 第0行移0位,第1行移1位,第2行移2位,第3行移3位。如图:
行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。
把输入的每列看做一个向量,然后与一个固定的矩阵在GF(2^8)扩展域上相乘。 这个固定矩阵是由给定的一个向量,这个向量通过逐位变换得到这个矩阵。
将上述矩阵求逆即可,即逆矩阵。