AES算法分析与实现

 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 密钥)主要加解密流程如下图所示:

AES算法加解密流程

 

 

图中左边是加密流程,右边是解密流程, 其中, 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值