AES加密算法实现流程

由于AES的数学原理在网上有很多,所以在这里就不再说明,主要是加密流程。

先说明一下AES的几个必备参数的初始化
typedef struct _AES{
    int    Nb;                                //明文或密文的行数
  int    Nr;                                //加密或解密时的轮数
  int    Nk;                                //密钥的行数           
  unsigned long    *Word;  //指向密钥库的指针
  unsigned long    *State;  //指向每一轮加密或解后的结果
}AES;
这里统一为4列n行,可以用unsigned long数组表示。
Nb = 明文或密文长度/4 ;Nk = 密钥长度/4;加密轮数Nr = Nb < Nk ? Nk:Nb+6;
 
一.密钥库的生成过程
  1.计算库的行数并分配内存
      库行数  = Nb*(Nr+1);
  2.初始化密钥库
      库的第一个密钥为原密钥---直接将密钥拷贝到密钥库中;
  3.开始计算轮密钥
      unsigned long temp;
      for (int c = Nk; c < Nb * (Nr+1); ++c)
      {
            //把上一轮的最后一行放入temp
            temp = w[c-1];
            //判断是不是每一轮密钥的第一行
            if (c % Nk == 0) 
            {
                  //左旋8位
                  temp = (temp<<8)|(temp>>24);
                  //查Sbox表
                  SubWord((byte*)&temp);
                    temp ^= Rcon[c/Nk];
                }
              else if ( Nk > 6 && (c % Nk == 4) ) 
              {
                    SubWord((byte*)&temp);
              }
              //w[c-Nk] 为上一轮密钥的第一行
              w[c] = w[c-Nk] ^ temp;
            }
 
二.State生成
    为了实现快速列混淆(这里应该是行混淆),State需要多出三行作为缓冲区。
    所以State = new unsigned long[Nb+3];
      当解密时State += 3;加密时不变。
AES算法中行混淆的实现:
      加密时第1,2,3列(从0开始)分别上旋(解密时下旋)1,2,3个字节。
    先拷贝前三行到State的最后三行(就是拷贝到多出来的那三行)。
    设temp(unsigned char temp[4])为行混淆后第n行的数据。
    设Nb = 4,那么加密时的逻辑结构为:(空白为无效数据)
        拷贝前:                            拷贝后:                            处理完后的结果:
            c0    c1    c2    c3    c0    c1    c2    c3        c0    c1    c2    c3
--------------------- --------------------- ---------------------
| s0 | s1 | s2 | s3 | | s0 |              | | t0 | t5 | ta | tf |
--------------------- --------------------- ---------------------
| s4 | s5 | s6 | s7 | | s4 | s5 |          | | t4 | t9 | te | t3 |
--------------------- --------------------- ---------------------
| s8 | s9 | sa | sb | | s8 | s9 | sa |      | | t8 | td | t2 | t7 |
--------------------- --------------------- ---------------------
| sc | sd | se | sf | | sc | sd | se | sf | | tc | t1 | t6 | tb |
---------------------  --------------------- ---------------------
                    | s1 | s2 | s3 | |                  |
---------------------  --------------------- ---------------------
                        | s6 | s7 | |                  |
---------------------  --------------------- ---------------------
                            | sb | |                  |
---------------------  --------------------- ---------------------
      则temp = {s0,s5,sa,sf};temp值经其它运算后放入State的第n行。
    下面是解密时的情况
      拷贝前:                            拷贝后:                            处理完后的结果:
          c0    c1    c2    c3    c0    c1    c2    c3        c0    c1    c2    c3
--------------------- --------------------- ---------------------
                | |              s7  | |                  |
--------------------- --------------------- ---------------------
                | |          sa  sb  | |                  |
--------------------- --------------------- ---------------------
                | |      | sd | se | sf  | |                  |
--------------------- --------------------- ---------------------
| s0 | s1 | s2 | s3 | | s0 | s1 | s2 | s3 | | t0 | td | ta | t7 |
---------------------  --------------------- ---------------------
s4  | s5  s6  s7  s4  | s5 | s6 |      | |  t4 |  t1  te  tb  |
---------------------  --------------------- ---------------------
s8  s9  sa  | sb  s8  s9          | |  t8  t5  t2  tf  |
---------------------  --------------------- ---------------------
sc  | sd  se  | sf  sc            | |  tc  t9  t6  t3  |
---------------------  --------------------- ---------------------
三.开始加密
    1.初始化第一轮
      State ^= 密钥库的第一轮密钥
  2.共Nr-1轮
      (1).先拷贝前三行到State的最后三行(就是拷贝到多出来的那三行)。
      (2).temp = {Sbox[s0],Sbox[s5],Sbox[sa],Sbox[sf]};
      (3).State第n行
              第一个字节=Log_02[temp[0]]^Log_03[temp[1]]^temp[2]^temp[3];
                第二个字节=Log_02[temp[1]]^Log_03[temp[2]]^temp[3]^temp[0];
              第三个字节=Log_02[temp[2]]^Log_03[temp[3]]^temp[0]^temp[1];
              第四个字节=Log_02[temp[3]]^Log_03[temp[0]]^temp[1]^temp[2];
      (4).State的当前行 ^= 密钥库的第n轮密钥相应行;
              再跳到(2),进行State的下一行计算
    3.最后一轮
        (1).先拷贝前三行到State的最后三行(就是拷贝到多出来的那三行)。
        (2).State的当前行 = {Sbox[s0],Sbox[s5],Sbox[sa],Sbox[sf]};
      (3).State的当前行 ^= 密钥库的最后一轮密钥相应行;
              再跳到(2),进行State的下一行计算
四.开始解密
  与加密时相反,从最后一轮开始。
    1.初始化最后一轮
        State ^= 密钥库的最后一轮密钥
  2.共Nr-1轮(Nr-1=>0)
      (1).先拷贝State的最后三行到State的前三行。
      (2).temp = {iSbox[s0],iSbox[sd],iSbox[sa],iSbox[s7]};
      (3).State的当前行 ^= 密钥库的第n轮密钥的相应行;
      (4).State第n行
              第一个字节 = Log_0e[temp[0]] ^ Log_0b[temp[1]] ^
                                      Log_0d[temp[2]] ^ Log_09[temp[3]];
                第二个字节  = Log_0e[temp[1]] ^ Log_0b[temp[2]] ^
                                      Log_0d[temp[3]] ^ Log_09[temp[0]];
              第三个字节 = Log_0e[temp[2]] ^ Log_0b[temp[3]] ^
                                      Log_0d[temp[0]] ^ Log_09[temp[1]];
              第四个字节 = Log_0e[temp[3]] ^ Log_0b[temp[0]] ^
                                      Log_0d[temp[1]] ^ Log_09[temp[2]];
              再跳到(2),进行State的下一行计算
    3.最后一轮
      (1).先拷贝State的最后三行到State的前三行。
      (2).State的当前行 = {iSbox[s0],iSbox[sd],iSbox[sa],iSbox[s7]};
      (3).State的当前行 ^= 密钥库的第一轮密钥相应行;
              再跳到(2),进行State的下一行计算
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值