逆向算法--对称算法之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),一般这个就是主要的加密循环

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