IV 与 nonce 怎么用
IV 与 nonce 都是「初始化参数」:它们决定同一密钥下加密结果的随机性,无需保密但绝不能可预测或重复。不同模式的要求不同——CBC 需要随机且不可预测的 IV,CTR 与 GCM 需要同一密钥下唯一的 nonce。混淆这两类要求是最常见的加密实现错误之一。
基本信息
| CBC 的 IV | 16 字节随机数,随密文一起存储 |
|---|---|
| GCM/CTR 的 nonce | 推荐 12 字节,同一密钥下必须唯一 |
| 是否需要保密 | 不需要,但必须防预测与重用 |
| 存储方式 | 通常前置在密文或文件头部,或存入数据库字段 |
| 生成来源 | 密码学安全随机数,如 openssl rand 或 os.urandom |
| 常见错误 | 固定值、计数器当随机数、失败重试时重用 |
典型使用场景
- 文件加密:每次加密生成随机 IV 并随文件保存
- 数据库字段加密:每行或每次更新生成新 nonce
- 协议实现:按会话或消息序号构造结构化 nonce
- 批量加密:为每条记录分配不重叠的 nonce 区间
- 排错与审计:核对密文格式,确认 nonce 是否被正确保存
生成与使用
生成与使用
# 生成 16 字节随机 IV(32 个十六进制字符)
openssl rand -hex 16
# 生成 12 字节 GCM nonce
head -c 12 /dev/urandom | xxd -p
# Base64 形式便于放进配置或接口字段
openssl rand -base64 12
# OpenSSL 口令模式下 salt 与 IV 的处理由工具负责,注意迭代次数要随文件保存模式要求对照
| 模式 | IV/nonce 要求 | 重复使用的后果 |
|---|---|---|
| ECB | 无 IV | 相同明文块产生相同密文块,结构泄漏 |
| CBC | 随机且不可预测 | 退化为确定性加密,相同明文产生相同密文 |
| CTR | 同一密钥下唯一 | 密钥流重叠,可恢复明文 |
| GCM | 同一密钥下唯一(推荐 96 位) | 认证子密钥泄漏并允许伪造消息 |
| XTS | 按扇区编号派生 | 跨扇区重用会泄漏扇区间的关系 |
把 IV 写成常量,或在失败重试时复用同一 nonce,是高频实现错误。对流模式(CTR/GCM)而言,nonce 重用不仅泄漏明文,还会泄漏认证密钥并可伪造消息,其后果等同于密钥泄漏;解密失败重试路径尤其要检查。
IV 需要「防预测」不一定需要「随机」:CTR 与 GCM 允许使用结构化计数器构造 nonce,只要保证同一密钥下不重叠即可。随机来源必须可靠,用时间戳或普通随机函数生成 IV 会引入可预测性。