AES加密算法

和DES加密算法相比,AES提供了更高的安全性,在TLS握手后的数据传输阶段,所使用的共享密钥算法就是AES加密模式。

AES, Advanced Encryption Standard,其实是一种FIPS 197标准。美国NIST (National INstitute of Standards and Technology)在1997年公开征集的替代DES加密算法中,有5种算法入选决赛,即MARS,RC6,Rijndael,Serpent和Twofish。经过多轮的测试验证讨论,Rijndael算法最终入选。我们目前所使用的AES,其实就是利时学者Joan Daemen和Vincent Rijmen所提出的Rijndael算法。

AES和Rijndael算法总览

Rijndael算法支持多种分组及密钥长度,只要该长度为128-256之间32的倍数。而AES标准支持的分组大小固定为128位,密钥长度有3种选择:128位、192位及256位。密钥长度的不同,最终体现在加密轮数的差异上。

和DES所使用的Feistel网络结构不同,Rijndael采用的是SPN(Substitution-permutation network)结构进行迭代计算。每一次的迭代称为一轮(又称为轮函数),轮函数分别由SubBytes、ShiftRows、MixColumns和AddRoundKey共4个步骤组成。其中的步骤AddRoundKey涉及到密钥扩展(KeyExpansion)。总的来说,Rijndael算法包括两大部分,明文的迭代计算和密钥扩展。

本文以128bit(即16 Byte)明文和密钥长度为例,来分析讨论Rijndael加密算法的构成以及部分C语言实现,而解密算法为加密算法的逆运算,为了集中重点,解密算法本文不作分析。而当明文超过128bit时,需要使用分组加密模式进行迭代,加密模式也不在本文的讨论范围。

Rijndael 128bit(16 Byte)加密模式总览图如下:

                                                          

一、明文分组的迭代算法

当明文分组长度为128bit,16Byte时,将其分为4x4 Byte的矩阵。如果密钥长度为128位,则分为11轮迭代计算,除去第一轮和最后一轮外(见上图),其他9轮为以下4个步骤的迭代:

 SubBytes-->ShiftRows-->MixColumns-->AddRoundKey

1. SubBytes

即字节置换(Substitute Bytes)。

128bit的明文分组重组的4x4字节矩阵中,每一个字节通过S盒进行置换,和Des不同,SubBytes代码实现中,常量表示的S盒,有着严格的数学定义。

单个字节a的置换过程如下:

  • 取该字节a的高4位,用该值定位于S盒的行号
  • 取该字节a的低4位,用该值定位于S盒的列号
  • 用上述已定位的行和列的交叉点字节替换原数据字节a

示例如下:

C语言实现代码如下:

void aes_sub_bytes(uint8_t *state)
{
    int i, j;
   
    for (i = 0; i < 4; i++) { /* 4 Rows */
        for (j = 0; j < 4; j++) {
            state[i * 4 + j] = aes_sbox[state[i * 4 + j]];  /* column  */
        }
    }
}

上述代码中,aes_sbox为256字节的常量表,其内容为上图左侧表格中的数据值。

2. ShiftRows(行移位)

行移位主要目的是实现字节在每一行的扩散,属于线性变换。

4x4的字节矩阵通过以下规则进行循环字节移位:

状态矩阵的第0行左移0字节,第1行循环左移1字节,第2行循环左移2字节,第3行循环左移3字节。

如图:

3. Mix Columns(列混合)

轮函数的4个步骤中,列混合最为复杂。

列混合是通过将第2步行移位后的矩阵与常矩阵C相乘以实现在列上的扩散,属于代替变换,其实质是在有限域GF(2^8)上的多项式乘法运算。

混合运算过程如下:

即a'1,0为中间表中第一列与常量表S中的第一行相乘,a'1,0为中间表中第一列与常量表S中的第二行相乘,a'2,0为中间表中第一列与常量表S中的第三行相乘,a'3,0为中间表中第一列与常量表S中的第四行相乘。
这里的行列相乘,即上图中同色块元素的相乘。

首先介绍一些矩阵元素运算的背景知识。
矩阵元素的乘法和加法都是定义在基于GF(2^8)上的二元运算,并不是通常意义上的乘法和加法。这里涉及到一些信息安全上的数学知识,这种二元运算的加法等价于两个字节的异或,乘法则复杂一点。

  • 单个字节a的二元运算x2的算法规则为:
    如果该字节a的bit7(最高位)为1,则和0x1B异或;否则,a左移一位,低位补0。
  • 单个字节a的二元运算x3的算法规则为:
    为x2的合成运算,即3 x a = (2 x a) ⊕ a

下面以a'0,0为例,具体解析其计算获得过程:

a'0,0= (2 x a0,0) ⊕ (3 x  a1,0) ⊕ a2,0⊕ a3,0

然后将2x,3 x带入上面背景知识中的二次元相应运算即可。

列混合的C代码实现如下:

uint8_t Y[16] = {
        2, 3, 1, 1,  
        1, 2, 3, 1,  
        1, 1, 2, 3,  
        3, 1, 1, 2
};

void aes_mix_columns(uint8_t *state)
{
    uint8_t s[4];
    int j, r;
     
    for (r = 0; r < 4; r++) { /* 为Y表行索引,共4行 */
        s[r] = 0;
        for (j = 0; j < 4; j++) { /* j为一列中的一个元数据  */
            /*   */
            s[r] = s[r] ^ aes_mul(state[j], Y[r * 4 + j]); 
        }
    }

    for (r = 0; r < 4; r++) {
        state[r] = s[r];
    }

}

上面代码中的函数aes_mul实现如下:

uint8_t  mul2(uint8_t state)
{
    return ((state << 1) ^ (((state >> 7) & 1) * 0x1b));
}

uint8_t  aes_mul(uint8_t state, uint8_t x)
{
    if (x == 1)
        return state;
    else if (x == 2)
        return mul2(state);
    else if (x == 3)
        return mul2(state) ^ state;

}

上述代码只考虑了x1,x2,x3的情况,且未考虑其他无效的返回值。 

 4. AddRoundKey(轮密钥加)

轮密钥加比较简单,将轮密钥与其前一步(注意第一轮和最后一轮迭代步骤)的矩阵状态值进行逐字节异或。

二、密钥扩展

密钥扩展算法目的是根据种子密钥生成多组轮密钥。对应128、196和256位密钥,分别扩展生成11、13、15组轮钥,这里的11、13,15即为11 x 4 word、13 x 4 word,15 x 4 word,每word 32bit,即128bit。其实质是根据迭代轮数不同,生成相应轮数的轮密钥。

下面以128bit密钥为例,来说明轮密钥的生成过程。

1. 密钥重组

128bit的原始密钥组成4x4的字节矩阵,并将一列4个字节重组为一个字(word),共4W:

2. 密钥扩展

密钥扩展流程如下(j为迭代轮数,1<= j <= 10):

其中第一轮密钥为原始密钥,后续的10轮密钥均由轮密钥扩展计算得到。

其扩展规则为:
1).如果i不是4的倍数,那么第i列由如下等式确定:

W[4j + i]=W[4j + i-4] ⨁ W[4j + i-1]

其中1<= i <= 3。

2).如果i为0,即4j+i为4的倍数,那么第j轮第0列由如下等式确定:

W[4j]=W[4j-4] ⨁ T(W[4j -1])

T函数定义为:

 即T函数由“字循环移位+S盒置换+常量表异或”三个步骤构成。

实现代码略。

参考:

​​​​​AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客_aes加密

https://github.com/matt-wu/AES

《图解密码学》

《https权威指南》

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值