AES 加密完整指南:原理、模式与实战应用

你的 HTTPS 连接、手机存储、Wi-Fi 密码、ZIP 压缩文件保护——几乎所有现代加密场景的核心都是同一个算法:AES(Advanced Encryption Standard)。它是 2001 年由 NIST 选定的对称加密标准,至今仍被视为无法破解的实用加密基石。理解 AES 的运作方式,是每位开发者和信息安全从业者的必备知识。

1. AES 的由来

1997 年,NIST(美国国家标准与技术研究院)宣布举办公开竞赛,寻找 DES(Data Encryption Standard)的继任者。DES 的 56 位密钥在 1999 年被以 22 小时暴力破解,已不够用。

历经五年、全球密码学家的公开审查,2001 年 NIST 选定由比利时密码学家 Joan Daemen 和 Vincent Rijmen 设计的 Rijndael 算法,正式命名为 AES,发布为 FIPS PUB 197 标准。

对称加密 vs. 非对称加密
AES 是对称加密:加密和解密使用同一把密钥。相对地,RSA 是非对称加密,使用公钥加密、私钥解密。HTTPS 实际上是两者结合:用 RSA/ECDH 安全交换 AES 密钥,再用 AES 加密实际传输的数据。

2. AES 的密钥长度

AES 支持三种密钥长度,安全性依次递增:

密钥长度轮数安全级别主要用途
AES-12810 轮128 位一般消费性应用、TLS
AES-19212 轮192 位较少使用
AES-25614 轮256 位政府机密、高安全性需求

AES-128 对绝大多数应用已绰绰有余——暴力破解需尝试 2¹²⁸ 种组合,以现有算力约需宇宙年龄的倍数。AES-256 常见于合规要求(如美国政府 TOP SECRET 数据必须使用 AES-256)。

3. AES 如何运作

AES 以 128 位(16 字节)为一个区块处理数据。密钥长度决定轮数,每轮执行四个步骤:

3.1 四个核心步骤

  1. SubBytes(字节替换):将每个字节通过固定的 S-Box 查表替换,提供非线性混淆
  2. ShiftRows(行移位):将 4×4 字节矩阵的各行循环左移不同位数,打散数据位置
  3. MixColumns(列混合):对每列进行有限域乘法运算,使各字节互相影响(最后一轮省略)
  4. AddRoundKey(加入轮密钥):将当前状态与由主密钥衍生的轮密钥做 XOR 运算

4. 加密模式:最关键的选择

AES 本身只定义如何加密单一 128 位区块。面对任意长度的数据,需要选择「加密模式」。这个选择比密钥长度更重要。

4.1 ECB(电子密码本模式)— 永远不要用

ECB 是最简单的模式:每个区块独立加密。致命弱点:相同的明文区块产生相同的密文区块,保留了原始数据的模式,完全不安全。

ECB 企鹅问题
用 ECB 加密一张企鹅图片,加密后仍能清楚看出企鹅轮廓——因为颜色相同的像素区域会产生相同的密文。ECB 在任何需要保密的场景都不应使用。

4.2 CBC(密文块链接模式)— 传统选择

CBC 在加密前将每个明文块与前一个密文块做 XOR,第一个块与随机生成的 IV(初始化向量)做 XOR。需要 Padding,本身不提供完整性验证,容易受到 Padding Oracle 攻击。

4.3 CTR(计数器模式)— 让 AES 成为流加密

CTR 模式加密一个递增的计数器值,再将输出与明文 XOR。不需要 Padding,可完全并行处理,但不提供完整性验证。

4.4 GCM(伽罗瓦计数器模式)— 现代首选

GCM = CTR 加密 + GHASH 认证码。在提供加密的同时,自动生成 Authentication Tag(认证标签),用于验证密文未被篡改。

  • 认证加密(AEAD):同时保证机密性和完整性
  • 不需要 Padding,性能好
  • 现代 TLS 1.3 主要使用 AES-256-GCM
模式需要 Padding完整性验证可并行推荐程度
ECB❌ 绝对不用
CBC部分⚠️ 旧系统兼容
CTR✅ 可用(需另加 MAC)
GCM✅ 内置✅✅ 现代首选

5. IV 和 Nonce:千万不能重用

CBC 需要 IV,GCM 需要 Nonce(一次性随机数)。这是 AES 使用中最容易出错的地方:

  • 每次加密都必须使用不同的 IV/Nonce——重用会严重削弱安全性
  • IV/Nonce 不需要保密,可以与密文一起明文传输
  • GCM Nonce 重用是灾难性的:攻击者可以恢复认证密钥,完全破解整个加密方案
重要原则
永远使用随机生成的 IV/Nonce,永远不要硬编码或复用。使用密码学安全的随机数生成器(如 PHP 的 random_bytes()、Python 的 os.urandom())。

6. 实战代码示例

# PHP(使用 OpenSSL,AES-256-GCM)
$key = random_bytes(32);          // 256 位密钥
$nonce = random_bytes(12);        // 96 位 Nonce
$ciphertext = openssl_encrypt(
    $plaintext, 'aes-256-gcm', $key,
    OPENSSL_RAW_DATA, $nonce, $tag
);

// 解密
$decrypted = openssl_decrypt(
    $ciphertext, 'aes-256-gcm', $key,
    OPENSSL_RAW_DATA, $nonce, $tag
);

# Python(使用 cryptography 库,AES-256-GCM)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

key = os.urandom(32)          # 256 位密钥
nonce = os.urandom(12)        # 96 位 Nonce
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
plaintext = aesgcm.decrypt(nonce, ciphertext, None)

# Node.js(内置 crypto 模块,AES-256-GCM)
const crypto = require('crypto')
const key = crypto.randomBytes(32)
const nonce = crypto.randomBytes(12)
const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce)
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()])
const tag = cipher.getAuthTag()  // 16 字节认证标签

7. 常见问题

7.1 AES 被破解了吗?

目前没有任何实际可行的 AES 攻击。最好的已知理论攻击将 AES-128 的暴力搜索空间缩小了 4 倍,但仍需 2¹²⁶·¹ 次操作,在可预见的未来完全不可行。AES 的安全性主要取决于密钥管理和加密模式的正确使用。

7.2 量子计算机会让 AES 失效吗?

Grover 算法让量子计算机能将对称加密的有效安全性折半——AES-128 降为 64 位(不够安全),AES-256 降为 128 位(仍然安全)。因此 AES-256 被认为是后量子安全的对称加密方案,AES-128 在量子威胁下可能不足。

7.3 加密就够了吗?

不够。加密只保护机密性,不防止篡改。现代加密应使用 AEAD,如 AES-GCM,同时提供加密和完整性验证。仅使用 AES-CBC 而不加 HMAC 的系统容易受到 Padding Oracle 等攻击。

8. 小结

AES 是现代密码学的基石:经过二十多年的公开审查,至今仍无法破解。但演算法本身只是一部分——正确使用才是关键:使用 GCM 模式(而非 ECB 或裸 CBC)、每次加密使用随机 Nonce以 KDF 派生密钥而非直接使用密码。掌握这些原则,AES 能为你的应用提供工业级的加密保护。