AUTHOR: Jeffrey.zhu
BLOG:http://blog.youkuaiyun.com/gueter/
AES 算法的主要数学基础是抽象代数,其中算法中的许多运算是按单字节( 8bits )和 4 字节( 32bits )定义的,单字节可看成有限域 GF(28 ) 中的一个元素,而 4 字节则可以看成系数在 GF(28 ) 中并且次数小于 4 的多项式(亦可以理解为: GF(2564 ) ),单字节上的运算有两种:有限域 GF(28 ) 上一个 8 次不可约多项式的模加、点乘(为方便代码实现,推出了 X 乘的概念),其中,这个不可约多项式为: m(x)= x8 +x4 +x3 +x+1 ,类似地, 4 字节运算也分为两种:模加、乘法(为方便代码实现,推出了模乘的概念),而此时使用的模取 M(x)=x4 +1 ,由于 x4 +1=( x2 +1)( x2 +1)= ( x+1) ( x+1) ( x+1) ( x+1) ,即非不可约,导致非 0 多项式乘法逆元(逆元求取主要用到了欧几里德( Euclid )算法)不一定存在,所以在 AES 算法中,只限于乘一个固定的有逆元的多项式: a(x)={03}x3 +{01}x2 +{01}x+{02} 。
AES ( 128bits 密钥)主要加解密流程如下图所示:
图中左边是加密流程,右边是解密流程, 其中, Plaintext 为明文, Ciphertext 为密文, 密钥长度可变,可指定为 128 、 192 、 256 比特,不同密钥长度决定了加解密算法的轮数( 128 位: 10 轮, 192 位: 12 轮, 256 位: 14 轮),算法征集之初, 6 轮迭代便可抵抗当时世界上已知的所有攻击, AES 标准中至少留了 4 轮余量,按照这种说法,可以推知轮数越多, AES 破解难度越大,也就是密钥越长越安全,所以今年 8 月份有人说 256bits 密钥长度的 AES 算法被破解,而 128bits 未被破解是没有根据的。
理解 AES 需要知道以下两个概念:
l 状态:算法中间的结果也需要分组,称之为状态,状态可以用以字节为元素的矩阵阵列表示,该阵列有 4 行,列数 Nb 为分组长度除 32 ;
l 种子密钥:以字节为元素的矩阵阵列描述,阵列为 4 行,列数 Nk 为密钥长度除 32 ,其中根据种子密钥,可以推导出 各轮子密钥 w[ , ] ,此过程亦称作密钥扩展,针对不同密钥长度的密钥扩展算法可以参照阅读 AES 算法标准发布文档。
1 )下面简单分析一下 AES(128bits 密钥 ) 的加密流程:
AESEncrypt (State, ExpandedKey)
{
AddRoundKey (State, ExpandedKey); // 种子密钥加,实际已经进行过子密钥扩展
for (i=1; i <Nr; i ++) //Nr 根据密钥长度进行取值
Round (State, ExpandedKey+Nb* i);// 加密轮函数
FinalRound (State, ExpandedKey+Nb*Nr);// 加密最后一轮轮函数
}
l 加密轮函数:
Round (State, RoundKey)
{
ByteSub (State); // 字节替代变换
ShiftRow (State);// 行移位变换
MixColumn (State);// 列混合变换
AddRoundKey (State, RoundKey)// 子密钥加(其实是一个简单的逐比特模 2 加)
}
l 加密最后一轮轮函数:
FinalRound (State, RoundKey)
{
ByteSub (State);// 字节替代变换
ShiftRow (State);// 行移位变换
AddRoundKey (State, RoundKey);// 子密钥加
}
以上加密过程具体算法可参照 AES 标准发布文档,需要注意的地方有以下几点:
l 字节替代变换是一种非线性变换,主要有两个可逆变换组成:求逆元、仿射变换,在具体实现中,根据两个过程的特点,逐一计算 00~FF 共 256 种字节替代变换结果,可以推导出一个固定的、加密用的 S 盒表;
l 列混合变换,即将状态的每一列视为有限域 GF(28 ) 上的一个多项式,并将此多项式与一个具有逆元的多项式进行多项式乘法,这个具有逆元的多项式即为前述的 a(x)={03}x3 +{01}x2 +{01}x+{02} ,它的逆元为: a-1 (x)={0b}x3 +{0d}x2 +{09}x+{0e} ;
l 基于种子密钥的子密钥扩展过程必须发生在调用加密函数之前,且加密完之后,传送到解密方的是种子密钥,也就是说,在调用解密函数之前也必须基于种子密钥进行子密钥扩展,此外,针对不同的密钥长度有不同的子密钥扩展算法,具体参照 AES 标准发布文档;
l 最后一轮轮函数之所以去掉列混合,是因为最后一轮的列混合并未增加 AES 算法的安全性,反而增加其实现难度,降低算法效率。
2 )下面简单分析一下 AES(128bits 密钥 ) 的解密流程:
AESDecrypt (State, ExpandedKey)
{
AddRoundKey (State, ExpandedKey+Nb*Nr);// 子密钥加
for (i= Nr-1; i >=1; i --) // Nr 根据密钥长度进行取值
InvRound (State, InvMixColumn (ExpandedKey+Nb* i));// 解密轮函数
InvFinalRound (State, ExpandedKey); // 解密最后一轮轮函数
}
l 解密轮函数:
InvRound (State, RoundKey)
{
InvShiftRow (State);// 逆移位变换
InvByteSub (State);// 逆字节替代变换
AddRoundKey (State, RoundKey);// 子密钥加
InvMixColumn (State); // 逆列混合变换
}
l 解密最后一轮轮函数:
InvFinalRound (State, RoundKey)
{
InvShiftRow (State);// 逆移位变换
InvByteSub (State);// 逆字节替代变换
AddRoundKey (State, RoundKey);// 逆列混合变换
}
以上解密过程具体算法可参照 AES 标准发布文档,需要注意的地方有以下几点:
l 加密过程中的子密钥加的逆变换即为同一子密钥继续加,所以的解密算法调用之前要对扩展后的子密钥进行逆序;
l 加解密是使用同一个 S 盒表?还是分别采用各自的 S 盒表?是一个时间复杂度和空间复杂度的权衡(作者在实现中将加解密 S 盒表分开做);
l 逆移位变换与逆字节替代变换之间是可以相互调换位置的。
源代码:
www.mowker.com
3421

被折叠的 条评论
为什么被折叠?



