首页/安全/加密与证书速查/PBKDF2 口令派生
加密算法基础95 条

PBKDF2 口令派生

基于 HMAC 的迭代式口令派生(RFC 8018 定义于 PKCS#5 v2.1),通过大量迭代抬高离线破解成本;迭代参数需要随硬件进步持续上调。

加密与证书速查安全更新于 2026-10-13

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 命令行直接加解密的场景。

易错点

  • 沿用老系统的低迭代次数(1000 到 10000 次):现代 GPU 下几乎等于无保护,应尽快上调并迁移
  • 迭代次数硬编码在代码里:无法随硬件升级调整,建议写入配置并随散列或密文存储
  • 盐固定或过短:同一口令产生相同结果,撞库与彩虹表攻击更有效,必须每用户或每文件独立随机
  • 只升级参数不做迁移:老数据仍用旧参数,应设计登录或解密时重算的渐进式路径
  • 把 PBKDF2 用作通用密钥派生:协议场景更适合 HKDF,口令场景才需要这种故意变慢的设计

数据来源与参考

  • RFC 8018 §5.2(PBKDF2)
  • OWASP Password Storage Cheat Sheet
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌