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的下一行計算
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章