AES 是什么
AES(Advanced Encryption Standard)是 NIST 在 2001 年以 FIPS 197 发布的对称分组密码,用来接替只有 56 位有效密钥的 DES。它的分组固定为 128 位,密钥可选 128/192/256 位,对应 10/12/14 轮迭代;结构上是代换-置换网络(SPN),每轮依次做字节代换、行移位、列混合与轮密钥加,最后一轮省略列混合。TLS 流量、磁盘加密、压缩归档与数据库静态加密里出现的对称加密,绝大多数都是 AES。
基本信息
| 标准 | FIPS 197 / ISO 18033-3 |
|---|---|
| 分组长度 | 128 位(16 字节) |
| 密钥长度 | 128 / 192 / 256 位 |
| 轮数 | 10 / 12 / 14 轮,随密钥长度变化 |
| 轮密钥 | 密钥扩展产生 11 / 13 / 15 组 |
| 结构 | SPN:SubBytes、ShiftRows、MixColumns、AddRoundKey |
| 硬件加速 | x86 的 AES-NI、ARMv8 的 Crypto Extensions |
典型使用场景
- TLS 套件:TLS 1.3 的 TLS_AES_128_GCM_SHA256 与 TLS_AES_256_GCM_SHA384
- 磁盘与分区加密:Linux 的 LUKS/dm-crypt(aes-xts-plain64)、Windows BitLocker
- 文件与备份加密:openssl enc、7z 的 AES-256 选项、自研归档格式
- 数据库与对象存储的静态加密(透明数据加密、服务端加密)
- 网络数据面:IPsec ESP 的 AES-GCM、企业 VPN 设备的数据通道
- 无线与物联网:WPA2/WPA3 的 AES-CCMP、部分设备固件的镜像加密
OpenSSL 加解密示例
OpenSSL 加解密示例
# 口令加密:用 pbkdf2 从口令派生密钥,iter 抬高离线爆破成本
openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt -in plain.txt -out data.enc
# 解密:salt、迭代次数、模式必须与加密时一致,否则只会得到乱码
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -in data.enc -out plain.txt
# 显式给定密钥与 IV(均为十六进制),便于和程序对接
openssl enc -aes-256-cbc -K 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff -iv 000102030405060708090a0b0c0d0e0f -in plain.txt -out data2.enc
# 测量本机吞吐,判断是否需要硬件加速
openssl speed -elapsed -evp aes-128-cbc
openssl speed -elapsed -evp aes-256-gcm工作模式选择
| 模式 | 是否认证 | 典型用途 | 注意点 |
|---|---|---|---|
| ECB | 否 | 几乎无正当用途 | 相同明文块产生相同密文块,泄漏结构 |
| CBC | 否 | 兼容老系统与部分文件格式 | IV 必须随机不可预测,需另加 HMAC 才完整 |
| CTR | 否 | 协议数据面、随机访问的存储 | nonce 与计数器在同一密钥下不得重叠 |
| GCM | 是 | TLS、IPsec、数据库字段加密 | 96 位 nonce 绝不能重用 |
| XTS | 否 | 磁盘与分区加密 | 专为扇区设计,不适合文件与网络传输 |
| CCM | 是 | 物联网、WPA2 类受限环境 | 分组很小,标签长度可配但更短即更弱 |
AES 本体只做「分组到分组」的变换,填充、IV、计数器与完整性都由工作模式层负责。排错时先分清是算法问题还是模式问题:换密钥长度不会修复模式泄漏,调模式也不会改善密钥管理。
有 AES-NI 或 ARM 密码扩展的 CPU 上,AES-128 与 AES-256 的性能差距通常很小;在老设备或纯软件实现上差距会放大,可用 openssl speed 对照后再定密钥长度。
不要把「用了 AES-256」当成安全结论。密钥若来自硬编码字符串、口令未经 KDF 加盐派生、IV 写成常量,256 位密钥同样守不住数据。对称加密的安全性一半在算法,一半在密钥与 IV 的管理。
自研归档格式的最小骨架
自研归档格式的最小骨架
# 文件头(明文)+ 密文体(分块加密)
version=1 # 格式版本,便于日后换算法而不破坏老文件
alg=aes-256-gcm # 算法与模式标识,解密端据此选择路径
kdf=pbkdf2-hmac-sha256 # 口令派生算法,必须连同迭代次数一起写入
iter=600000 # 迭代次数写入文件,升级参数时老文件仍可解
salt=16字节随机 # 每文件独立盐,禁止全局固定
nonce/iv=每次加密随机 # 分块加密时每块一个独立 nonce 或整文件一个并保证唯一
tag=128位 # 认证标签紧随密文存储,缺失时无法完整校验
keyid=data-key-2026-10 # 使用密钥管理服务时记录密钥标识,便于轮换与追溯落地检查清单
- 密钥来源:由 KMS 或密钥管理服务下发,不写死在代码、镜像与配置仓库中
- 密钥分层:主密钥只用于包装数据密钥,数据密钥定期轮换并按密文记录 key id
- 模式与 IV:新系统一律 AEAD(GCM/ChaCha20-Poly1305)或 XTS(磁盘),不使用 ECB
- 参数随密文持久化:算法、模式、KDF 迭代次数、盐与 nonce 都写入文件头或数据库字段
- 解密路径统一报错:认证失败只返回一个错误码,不区分「标签错」与「内容错」,也不记录可被外部观测的耗时差异
- 回滚预案:算法或密钥切换前准备好双读能力,避免老密文无法解开
加密参数要「向前兼容」:把算法标识、迭代次数、盐与 nonce 随密文一起存,日后提高强度时才能既加密新数据、又解开旧数据。参数只存在内存或代码常量里,是升级时最常见的返工原因。