3. AES算法原理与性能特征

AES(Advanced Encryption Standard)是当前最广泛使用的对称分组密码算法,支持128/192/256位密钥长度,分组大小固定为128位。理解AES的算法原理与性能特征,是后续进行加解密性能调优的基础。

3.1 AES-128/192/256加解密流程

AES加密过程由多轮迭代组成,每轮包含四个基本操作:SubBytes、ShiftRows、MixColumns和AddRoundKey。不同密钥长度对应的轮数不同:

AES变体 密钥长度 轮数 最后一轮特殊处理
AES-128 128 bit (16 byte) 10 跳过MixColumns
AES-192 192 bit (24 byte) 12 跳过MixColumns
AES-256 256 bit (32 byte) 14 跳过MixColumns
性能提示:轮数增加直接导致计算量线性增长。AES-256比AES-128多40%的轮数,在软件实现中吞吐量通常下降30%~50%。选择密钥长度时需在安全强度与性能之间权衡。

解密流程与加密对称,使用逆操作:InvSubBytes、InvShiftRows、InvMixColumns和AddRoundKey。解密时轮密钥的使用顺序与加密相反。

AES-128加密/解密流程对比 加密流程 明文 (128 bit) AddRoundKey (轮密钥0) 第1~9轮 (SubBytes→ShiftRows→MixColumns→AddRoundKey) 第10轮 (SubBytes→ShiftRows→AddRoundKey) 密文 (128 bit) 解密流程 密文 (128 bit) 第10轮 (InvShiftRows→InvSubBytes→AddRoundKey) 第9~1轮 (InvShiftRows→InvSubBytes→AddRoundKey→InvMixColumns) AddRoundKey (轮密钥0) 明文 (128 bit) 关键差异说明 • 加密:先AddRoundKey,再执行9轮完整操作,最后1轮跳过MixColumns。 • 解密:先执行最后一轮逆操作,再执行9轮逆操作,最后AddRoundKey。 • 解密轮密钥顺序与加密相反,且InvMixColumns需要额外计算。 • 解密流程比加密多出InvMixColumns的逆变换,软件实现中解密通常比加密慢10%~20%。

3.2 轮函数详解

AES每轮由四个变换组成,每个变换都有明确的数学定义和性能特征:

3.2.1 SubBytes(字节代换)

使用16×16的S盒对状态矩阵中的每个字节进行非线性替换。S盒是AES安全性的核心,但查表操作在软件中可能引发缓存侧信道攻击。

3.2.2 ShiftRows(行移位)

对状态矩阵的每一行进行循环左移:第0行不移,第1行移1字节,第2行移2字节,第3行移3字节。该操作仅涉及字节索引重排,计算开销极低。

3.2.3 MixColumns(列混合)

将状态矩阵的每一列视为GF(2⁸)上的多项式,与固定多项式相乘。该操作是AES中最耗时的部分之一,涉及有限域乘法和异或运算。

3.2.4 AddRoundKey(轮密钥加)

将状态矩阵与轮密钥进行逐字节异或。该操作计算量小,但需要频繁访问轮密钥数组。

性能热点分析:在纯软件实现中,各操作的计算开销占比大致为:SubBytes(查表)占35%~40%,MixColumns占30%~35%,AddRoundKey占15%~20%,ShiftRows占5%~10%。优化应优先针对SubBytes和MixColumns。

3.3 密钥扩展

密钥扩展(Key Expansion)从原始密钥生成所有轮密钥。AES-128需要11个轮密钥(包含初始密钥),AES-192需要13个,AES-256需要15个。

密钥扩展的核心操作包括:

  • RotWord:将4字节字循环左移1字节。
  • SubWord:对4字节字应用S盒替换。
  • Rcon:与轮常数进行异或。

密钥扩展的计算量远小于加解密本身,但在密钥频繁更换的场景(如每个数据包使用不同密钥)中,密钥扩展可能成为瓶颈。

AES-128密钥扩展流程 初始密钥 (16B) 轮密钥0 (16B) 密钥扩展算法 轮密钥1~10 密钥扩展细节 1. 将初始密钥分为4个32位字:W[0], W[1], W[2], W[3] 2. 对于i ≥ 4: - 若i mod 4 ≠ 0:W[i] = W[i-4] ⊕ W[i-1] - 若i mod 4 = 0:W[i] = W[i-4] ⊕ SubWord(RotWord(W[i-1])) ⊕ Rcon[i/4]

3.4 软件实现中的性能热点

在纯软件实现中,AES的性能瓶颈主要集中在以下几个方面:

性能热点 原因分析 优化方向
S盒查表 SubBytes需要256次查表/轮,查表延迟高且可能触发缓存未命中 使用位切片技术、SIMD查表、预计算T表
MixColumns有限域乘法 GF(2⁸)乘法涉及条件分支和移位操作,计算密集 使用T表合并SubBytes和MixColumns、SIMD并行化
轮密钥加载 每轮需要加载16字节轮密钥,内存访问频繁 将轮密钥缓存到寄存器、使用展开循环减少加载次数
数据依赖链 每轮结果必须等待上一轮完成,难以指令级并行 多块并行处理(CTR/GCM模式天然支持)、流水线化
解密性能劣于加密 InvMixColumns比MixColumns更复杂,且需要额外计算 使用等效解密密钥、预计算逆T表
安全警告:使用T表(查找表)优化虽然能大幅提升性能,但可能引入缓存时间侧信道攻击。在安全敏感场景中,建议使用位切片实现或硬件AES指令(如AES-NI)。

3.5 性能基准数据

以下为典型软件实现(无硬件加速)在3.0GHz x86-64处理器上的单线程吞吐量参考值:

AES变体 加密吞吐量 解密吞吐量 密钥扩展耗时
AES-128 ~800 MB/s ~650 MB/s ~0.5 μs
AES-192 ~680 MB/s ~550 MB/s ~0.7 μs
AES-256 ~580 MB/s ~470 MB/s ~0.9 μs
调优建议:在支持AES-NI指令集的CPU上,AES-128加密吞吐量可达5~10 GB/s,比纯软件实现快10倍以上。性能调优的首要步骤是确认硬件是否支持AES-NI,并优先使用硬件加速。

3.6 代码示例:AES-128单块加密核心循环

// AES-128加密核心循环(C语言风格伪代码)
void aes128_encrypt(uint8_t state[16], const uint8_t round_keys[11][16]) {
    uint8_t i;
    
    // 初始轮密钥加
    add_round_key(state, round_keys[0]);
    
    // 第1~9轮
    for (i = 1; i <= 9; i++) {
        sub_bytes(state);        // S盒替换
        shift_rows(state);       // 行移位
        mix_columns(state);      // 列混合
        add_round_key(state, round_keys[i]);  // 轮密钥加
    }
    
    // 第10轮(无MixColumns)
    sub_bytes(state);
    shift_rows(state);
    add_round_key(state, round_keys[10]);
}

从代码可见,AES-128的10轮循环中,第1~9轮执行4个操作,第10轮执行3个操作。性能优化应重点关注sub_bytes和mix_columns函数的实现效率。