逆向算法--對稱算法之AES

AES算法分析

標籤(空格分隔): Reverse Crypto 對稱加密


AES簡介

  • AES是一種對稱分組加密,明文長度爲128位(16字節),密鑰長度爲16/24/32字節均可,通過置換與替換迭代加密,經過多輪操作形成密文。加密大體流程:

    1. 擴展輸入密鑰
    2. 通過多輪循環加密密文
  • 不同長度密鑰對應加密輪數如下表

    AES 密鑰長度(bit) 分組長度(bit) 加密輪數
    AES-128 128 128 10
    AES-192 192 128 12
    AES-256 256 128 14
  • 爲了方便討論,之後我們的所有例子都是針對AES-128的。


AES加密流程

AES密鑰擴展

  • AES密鑰擴展主要是將密鑰從NbNk字節擴充爲Nb(Nr+1)字節,對於AES-128,Nb=4,Nk=4,Nr=10。

  • 首先定義一個4個dword大小的數組w,用於存放初始密鑰key(unsigned char的數組),此處使用拷貝的辦法,部分程序採用將四個byte合併爲一個dword的辦法

    for (int i=0;i<Nk;i++){
        w[i*4]=key[i*4];
        w[i*4+1]=key[i*4+1];
        w[i*4+2]=key[i*4+2];
        w[i*4+3]=key[i*4+3];
    }
    
  • 之後對w進行擴充,擴充40列,流程如下:

Created with Raphaël 2.2.0start with i=Nki%4==0(Y/N)?W[i]=W[i-4]^T(W[i-1]))loop until i==Nk*(Nb+1)i==Nb+1EndW[i]=W[i-4]^W[i-1]yesnoyesno
* 對於T函數,可以分爲以下幾個部分
    
    * 循環左移,可以理解爲將最高8位放置到最低8位處(w爲4個uchar大小的數組)
    ```C
    tmp=w[0];
    for(i=0;i<3;i++)
        w[i]=w[i+1];
    w[3]=tmp
    ```
    
    * 進行s盒置換運算(將數據高4位與低四位分別作爲行地址,列地址索引查找s盒)
    ```C
	for (i = 0; i < 4; i++) {
		w[i] = s_box[16*((w[i] & 0xf0) >> 4) + (w[i] & 0x0f)];
    }
    ```
    
    * 與一個常量數組進行易或操作

AES密文加密

  • AES數據加密主要由四種運算構成,分別是sub_bytesshift_rowsmix_columns以及add_round__key

  • sub_bytes,本質上是查s盒,主要將數據(BYTE大小)分割成高4位與低4位,取高四位作爲行地址,低四位作爲列地址取s盒數據

    for(i=0;i<4;i++)
        for(j=0;j<Nb;j++){
            row=(state[Nb*i+j]&0xF0)>>4;
            col=state[Nb*i+j]&0x0f;
            state[Nb*i+j]=s_box[16*row+col];
        }
  • shift_rows,將整個數組以Nb個BYTE爲一組進行左移
    for(i=1;i<4;i++){
        s=0;
        while(s<i){
        tmp=state[Nb*i];
        for(k=1;k<Nb;k++)
            state[Nb*i+k-1]=state[Nb*i+k];
        state[Nb*i+Nb-1]=tmp;
        s++
        }
    }
  • mix_columns,相當於將shift_rows生成的矩陣與一個常數矩陣相乘,使用的是線性代數的矩陣乘法。

  • add_round_key,此步開始加入密鑰進行計算,將處理後的明文(mix_columns的返回)與密鑰進行易或,其中state爲處理後的明文,w爲擴展後的密鑰

    for(c=0;c<Nb;c++){
        state[Nb*0+c]^=w[4*Nb*r+4*c+0];
        state[Nb*1+c]^=w[4*Nb*r+4*c+1];
        state[Nb*2+c]^=w[4*Nb*r+4*c+2];
        state[Nb*3+c]^=w[4*Nb*r+4*c+3];
    }
  • 實際的加密過程大致如下,對於AES-128,是進行第0輪的add_round_key,之後進行9輪(1-10輪)的sub_bytes,shift_rows,mix_columns以及add_round_key,最終輪不進行mix_columns。
  • 對於AES-128,Nr=10
    add_round_key(state,w,0);
    
    for(r=1;r<Nr;r++){    //注意此處r=1
        sub_bytes(state);
        shift_rows(state);
        mix_columns(state);
        add_round_key(state,w,r);
    }
    
    sub_bytes(state);
    shift_rows(state);
    add_round_key(state,w,Nr);

AES在逆向中的識別

  • AES本身感覺特徵不是很明顯,一般插件(例如PEiD的KryptoAnalyzer)是使用查找s盒來進行判定,並且會給出引用,可以以此爲思路寫腳本判定

  • 在找到s盒之後可以使用IDA的引用查找來找到key_expansion與cipher,之後進行分析得到各個函數。

  • cipher的大循環特徵比較明顯,可以查看循環9次的while或者for(對於AES-128),一般這個就是主要的加密循環

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章