PBKDF2 是什么
PBKDF2(RFC 8018 定义于 PKCS#5 v2.1)是基于 HMAC 的迭代式口令派生函数:把口令加盐后用 HMAC 反复压缩若干万次,把每次尝试的成本抬到可接受的量级,从而拖慢离线爆破。它的迭代次数必须随硬件进步持续上调,老系统的 1000 次早已远低于当前建议。
基本信息
| 标准 | RFC 8018 §5.2 |
|---|---|
| 结构 | HMAC 迭代 + 盐,参数随结果一起存储 |
| 参考参数 | 按 OWASP 建议:SHA-256 约 600000 次、SHA-512 约 210000 次 |
| 盐 | 建议 16 字节随机,每用户或每文件唯一 |
| 输出 | 派生密钥长度可指定,如 32 字节 |
| 典型用途 | 文件加密密钥派生、合规场景口令存储、无线与磁盘加密 |
典型使用场景
- 文件加密:openssl enc 的 -pbkdf2 用口令派生对称密钥
- 口令存储:合规要求明确列举 PBKDF2 时可用,配合足够迭代次数
- 无线与磁盘加密:WPA2 与部分磁盘加密方案使用 PBKDF2 派生密钥
- 密钥库保护:用口令派生保护密钥库文件的密钥
- 兼容既有系统:老应用只支持 PBKDF2 时的过渡方案
两种常见用法
两种常见用法
# 1)文件加密:口令经 PBKDF2 派生密钥,迭代次数随文件一起保存
openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt -in plain.txt -out data.enc
# 解密时迭代次数必须一致,否则得到乱码
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -in data.enc -out plain.txt
# 2)应用内口令派生(Python):每个用户独立随机盐
python3 -c "import hashlib, os; salt=os.urandom(16); print(hashlib.pbkdf2_hmac('sha256', b'password', salt, 600000, dklen=32).hex())"
# 查看当前 OpenSSL 默认迭代次数(版本不同默认值不同,显式指定更稳妥)
openssl version -a | head -2参数与影响
| 参数 | 作用 | 设置不当的后果 |
|---|---|---|
| 迭代次数 | 抬高单次验证成本 | 过低等于没有防线,过高会拖慢登录与拖垮 CPU |
| 盐长度与来源 | 防止彩虹表与同口令同结果 | 固定盐或短盐会让撞库更有效 |
| 底层 HMAC | 决定单次迭代成本与兼容性 | SHA-1 仍可用但应优先 SHA-256 及以上 |
| 派生长度 | 输出密钥字节数 | 与目标算法不匹配会导致密钥截断或补零 |
| 参数存储 | 随散列或密文保存 | 写死在代码里会导致升级困难 |
PBKDF2 的迭代次数必须随硬件进步上调,但升级不能让老用户无法登录:常见做法是把算法与参数随散列一起存储(如 $pbkdf2-sha256$600000$...),校验成功后用新参数重算并覆盖,实现渐进式升级。
PBKDF2 对 GPU 与专用硬件的抵御能力弱于内存硬方案。新项目的口令存储优先考虑 Argon2id 或 scrypt;PBKDF2 更适合合规明确要求、或需要用 openssl 命令行直接加解密的场景。