AES算法详解与七大加密模式

Sher10ck 发布于 2026-04-06 175 次阅读


在学习AES算法之前,最先清楚地应当是七大加密模式,这七大加密模式下的AES加密有着天壤之别,因此本文将从AES的7大加密模式开始探究逐步挖掘AES算法

一、七大加密模式

1.ECB:Electronic Codebook,电子密码本模式

原理

每个分组独立(以下均先以AES-128来展开)

加密:Ci=EK(Pi)C_i = E_K(P_i)

解密:Pi=DK(Ci)P_i = D_K(C_i)

特点

  • 不需要 IV
  • 相同明文块,在相同密钥下会得到相同密文块
  • 可以并行加密、并行解密
  • 实现最简单

是否需要 padding

需要。因为它是按块处理的。如果明文长度不是块大小整数倍,就要 padding;除非你明确用 NoPadding 且数据本来就是整块对齐。

2.CBC:Cipher Block Chaining,密码块链接模式

每一块明文在加密前,先和前一个密文块异或。第一块使用 IV:C1=EK(P1IV)C_1 = E_K(P_1 \oplus IV)Ci=EK(PiCi1),i2C_i = E_K(P_i \oplus C_{i-1}), \quad i \ge 2

解密:P1=DK(C1)IVP_1 = D_K(C_1) \oplus IVPi=DK(Ci)Ci1P_i = D_K(C_i) \oplus C_{i-1}

特点

  • 需要 IV
  • 即使两个明文块相同,只要前面的链不同,密文通常也不同
  • 解决了 ECB 的“重复块泄露”问题
  • 加密是串行的,不能天然并行
  • 解密可并行(因为每块只依赖当前密文块和前一密文块)

IV 要求

CBC 的 IV 一般要求:

  • 长度等于块大小
  • 不可预测 / 随机
  • 同一密钥下最好不要重复

是否需要 padding

需要。

3.CTR:Counter,计数器模式

原理

CTR 把分组密码变成“密钥流生成器”

先对 nonce + counter 加密,得到一个密钥流块:Si=EK(NonceCounteri)S_i = E_K(\text{Nonce} \| \text{Counter}_i)

然后与明文异或:Ci=PiSiC_i = P_i \oplus S_i

解密同样也是异或:Pi=CiSiP_i = C_i \oplus S_i

特点

  • 不需要 padding
  • 可以随机访问某个块
  • 加密解密都可并行
  • 性能高,工程上很常用

4.GCM:Galois/Counter Mode,伽罗瓦/计数器模式

原理

GCM = CTR 加密 + GHASH 认证

它一边用 CTR 产生密钥流加密消息,一边对:

  • AAD(附加认证数据,不加密)
  • 密文
    做一个 GF(2^128) 上的认证计算,最后得到 tag。

输出一般是:

  • ciphertext
  • authentication tag

AAD 是什么

AAD 是“要认证但不加密”的数据,比如:

  • 协议头
  • 长度字段
  • 序号
  • 元数据

特点

  • 既保密,又防篡改
  • 可并行
  • 高性能
  • 现代协议里极其常见(TLS、IPsec 等)

5.CCM:Counter with CBC-MAC,计数器与 CBC-MAC 模式

原理

CCM = CTR 加密 + CBC-MAC 认证

和 GCM 一样,也是 AEAD,只是认证部分不是 GHASH,而是 CBC-MAC。

6.OFB:Output Feedback,输出反馈模式

原理

先用 IV 经加密器产生输出,再把这个输出继续送回加密器,形成密钥流:O1=EK(IV)O_1 = E_K(IV)Oi=EK(Oi1)O_i = E_K(O_{i-1})

然后:Ci=PiOiC_i = P_i \oplus O_i

解密同样:Pi=CiOiP_i = C_i \oplus O_i

特点

  • 不需要 padding
  • 本质上把分组密码变成同步流密码
  • 某个密文 bit 出错,只会影响解密后对应那一 bit
  • 不会像 CBC 那样大面积传播

7.CFB:Cipher Feedback,密码反馈模式

原理

把“前一个密文块”送进加密器,输出后与当前明文异或:

首块:C1=P1EK(IV)C_1 = P_1 \oplus E_K(IV)C1​=P1​⊕EK​(IV)

后续:Ci=PiEK(Ci1)C_i = P_i \oplus E_K(C_{i-1})Ci​=Pi​⊕EK​(Ci−1​)

解密时:P1=C1EK(IV)P_1 = C_1 \oplus E_K(IV)P1​=C1​⊕EK​(IV) Pi=CiEK(Ci1)P_i = C_i \oplus E_K(C_{i-1})Pi​=Ci​⊕EK​(Ci−1​)

特点

  • 不需要 padding
  • 可以按字节/按位工作,也可以按整块工作
  • 自同步:丢了一些数据后,经过若干反馈长度后有机会重新同步
  • 加密通常串行

二、AES详解

AES对称加密算法的地位:被美国国家标准与技术研究院于2001年正式采纳为联邦信息处理标准。

1、AES算法概述

AES是一种对称加密算法,数据被分割成固定大小的块(128位|16字节)进行加密,AES支持三种密钥长度,分别对应128、192、256。

2.AES加密原理

AES加密总体步骤

AES算法采用多轮变换操作实现加密,每轮都包含四个基本步骤:

1、字节替换:通过S盒实现非线性字节替换

2、行移位:对状态矩阵进行循环移位

3、列混淆:对列进行线性变换

4、轮密钥加:与轮密钥进行异或运算

我们可以发现AES几乎集成了传统加密方式的所有变换特点,因此其加密的复杂性也相对较高

AES的常见数据规格

AES-128:密钥长度128、分组长度128、轮数10

AES-192:秘钥长度192、分组长度128、轮数12

AES-256:密钥长度256、分组长度128、轮数14

对应关系通常记成:

  • Nb = 4,表示状态矩阵有 4 列(固定) #Nb = BlockSize / 32 = 128 / 32 = 4
  • Nk = 4/6/8,对应密钥字数(1字表示32字节) #Nk = KeySize / 32
  • Nr = 10/12/14,对应轮数 #Nr 由密钥长度决定

分块

AES一次处理16字节输入块,这16字节输入块会被排成4*4的状态矩阵state

如果明文块是:b0,b1,b2,,b15b_0,b_1,b_2,\dots,b_{15}

AES 内部通常按列填充为:[b0b4b8b12b1b5b9b13b2b6b10b14b3b7b11b15]\begin{bmatrix} b_0 & b_4 & b_8 & b_{12}\\ b_1 & b_5 & b_9 & b_{13}\\ b_2 & b_6 & b_{10} & b_{14}\\ b_3 & b_7 & b_{11} & b_{15} \end{bmatrix}

AES整体加密流程

AES不是一上来就循环加密,而是先进行初始轮密钥加、中间若干轮、最后一轮

下面以AES-128为例展开(以下名词分别对应前面写的4大步骤)

1)先执行一次AddRoundKey

2)前 9 轮

每轮执行:

SubBytes

ShiftRows

MixColumns

AddRoundKey

3)最后一轮

执行:

  • SubBytes
  • ShiftRows
  • AddRoundKey

注意:

最后一轮没有 MixColumns。

AES四大核心变换详解

1.AddRoundKey(轮密钥加)

把当前状态矩阵 State 与该轮的轮密钥逐字节异或:State=StateRoundKeyState = State \oplus RoundKey

2.SubBytes(字节代换)

它会对 State 中的每个字节单独替换:bS(b)b \mapsto S(b)

这个 S-box 不是随便查表,而是两步构造出来的:

第一步:在 GF(2^8) 中求乘法逆

把每个字节看成有限域 GF(2^8) 上的元素。
除了 0 以外,每个元素都取乘法逆元;0 特判为 0。

有限域使用的不可约多项式是:m(x)=x8+x4+x3+x+1m(x)=x^8+x^4+x^3+x+1

它对应十六进制 0x11B

第二步:做仿射变换

对逆元结果再进行一次线性/仿射变换,得到最终 S-box 输出。

所以 AES 的 S-box 不是任意常量表,而是有明确代数结构。

3.ShiftRows(行移位)

这一步对 State 的每一行做循环左移:

  • 第 0 行:不移
  • 第 1 行:左移 1 字节
  • 第 2 行:左移 2 字节
  • 第 3 行:左移 3 字节

4.MixColumns(列混合)

对 State 的每一列,都把 4 个字节当成一个向量,然后与固定矩阵相乘:[02030101010203010101020303010102][s0s1s2s3]\begin{bmatrix} 02 & 03 & 01 & 01\\ 01 & 02 & 03 & 01\\ 01 & 01 & 02 & 03\\ 03 & 01 & 01 & 02 \end{bmatrix} \cdot \begin{bmatrix} s_0\\ s_1\\ s_2\\ s_3 \end{bmatrix}

乘法和加法都不是普通整数运算,而是在 GF(2^8) 中进行:

  • 加法 = XOR
  • 乘法 = 有限域乘法

三、AES 解密过程

AES 解密不是“把加密倒着写一下”那么简单,但思路就是对每步做逆运算,这边不做详细阐述了

对应四个逆变换:

  • InvSubBytes
  • InvShiftRows
  • InvMixColumns
  • AddRoundKey(异或自己就是逆)

解密大致流程是:

  1. 先加最后一轮轮密钥
  2. 做若干轮逆变换
  3. 最后一轮不做 InvMixColumns

逆矩阵对应为:[0E0B0D09090E0B0D0D090E0B0B0D090E]\begin{bmatrix} 0E & 0B & 0D & 09\\ 09 & 0E & 0B & 0D\\ 0D & 09 & 0E & 0B\\ 0B & 0D & 09 & 0E \end{bmatrix}

这也是在 GF(2^8) 上运算。

四、AES 的密钥扩展(Key Schedule)

AES 不是每轮都直接拿原始密钥来异或,它会先把主密钥扩展成多个 轮密钥

1.AES-128 密钥扩展核心操作

设原始密钥分成 4 个 word:W0,W1,W2,W3W_0,W_1,W_2,W_3

后面逐步生成:W4,W5,,W43W_4,W_5,\dots,W_{43}

规则大致是:

  • i mod Nk != 0,则 #Nk是前面说的key的字数(32bit为一字,放在128里Nk==4)

Wi=WiNkWi1W_i = W_{i-Nk} \oplus W_{i-1}

  • i mod Nk = 0,则

Wi=WiNkg(Wi1)W_i = W_{i-Nk} \oplus g(W_{i-1})

其中函数 g() 包括:

  1. RotWord:循环左移 1 字节
  2. SubWord:每字节过 S-box
  3. Rcon:与轮常量异或

RotWord

例如:[a0,a1,a2,a3][a1,a2,a3,a0][a_0,a_1,a_2,a_3] \rightarrow [a_1,a_2,a_3,a_0]

SubWord

把 4 个字节分别经过 AES S-box 替换。

Rcon

轮常量一般写成:

  • 01 00 00 00
  • 02 00 00 00
  • 04 00 00 00
  • 08 00 00 00
  • 10 00 00 00
  • ...

本质是有限域中的幂递推。

AES-256 的密钥扩展稍复杂

AES-256 中:

  • Nk = 8
  • 某些位置除了 g() 外,还会额外做一次 SubWord

所以 AES-256 的 key schedule 和 AES-128 并不只是“多几轮”那么简单。

五、总结

AES负责将16字节明文进行加密,而加密模式负责把输入的内容(任意长度)拆成多组16字节的内容再进行加密,实现AES加密的连续性。本人目前尚未见过对于AES算法的魔改题目,因此,做 CTF 逆向和应急,AES 最重要的不是“背算法”,而是知道什么时候它是标准实现、什么时候它被错误使用、什么时候它被故意改坏,以及你该从哪里把 key 和模式证据挖出来。

此作者没有提供个人介绍。
最后更新于 2026-04-06