PBKDF2 的迭代次数该怎么定

工具相关 ·

PBKDF2 的参数配置比 Bcrypt 和 Argon2 都要简单——它只有一个安全旋钮:迭代次数。简单有简单的好处,但也有一个代价:所有安全压力都压在这一个数字上。设低了保护不足,设高了登录变慢,而且这个数字会随着硬件进步不断变得不够用。

迭代次数做了什么

PBKDF2 的原理是:把 HMAC 反复迭代指定的次数,把每次迭代的结果异或起来。

设迭代次数为 c,那么计算一次派生结果就需要执行 c 次 HMAC 运算。攻击者每尝试一个候选口令,也要付出 c 倍的计算代价。

所以迭代次数的本质是给攻击者的每次尝试加上一个乘法因子。c 从 1000 提到 1000000,攻击速度就降到原来的千分之一。

这个机制与 Bcrypt 的 cost 因子思路相同,区别在于 PBKDF2 的调整是线性的——次数翻十倍,耗时翻十倍。而 Bcrypt 的 cost 加 1 就是翻倍,调整粒度更粗。

该取多少

OWASP 给出的建议值是目前最权威的参考:

HMAC 算法建议迭代次数参考耗时
HMAC-SHA11300000约 3.5 秒
HMAC-SHA256600000约 1.6 秒
HMAC-SHA512210000约 0.7 秒

可以看出,算法越强(SHA-512 比 SHA-256 每轮更慢),需要的迭代次数越少,因为单轮成本已经更高了。三组参数的目标耗时大致在同一量级。

不过这些数字要结合实际情况看。3.5 秒的校验时间对登录接口来说太长了,用户会明显感到卡顿。所以 OWASP 的建议值更适合作为「上限参考」,实际部署时通常需要按自己的服务器算力下调。

用耗时倒推更实际

与 Bcrypt、Argon2 一样,推荐的目标是让单次校验落在 100 到 500 毫秒之间。

按这个目标实测,HMAC-SHA256 在普通服务器上大约对应 10 万到 30 万次迭代。这个范围既保证了足够的攻击成本,又不会让用户等太久。

一定要在接近生产的硬件上实测。开发机上的耗时可能是服务器的三分之一,用开发机的数据定参数,上线后会发现登录慢了好几倍。

还要考虑并发。单次校验 200 毫秒听起来可以接受,但如果登录接口的峰值并发是每秒 500 次,那就是 100 个 CPU 核心满载。这种情况下要么降低迭代次数,要么对登录接口做限流,要么把校验放到独立的服务上。

迭代次数过高的问题

除了体验变差,迭代次数过高还有一个安全副作用:它会成为拒绝服务的放大器。

攻击者用大量错误密码发起登录请求时,服务器每一次都要完整执行一遍高代价的校验。如果单次校验需要 1 秒,攻击者每秒发 100 个请求,就能占满 100 个核心的计算时间。攻击者消耗的只是网络带宽,成本极低。

所以参数的上限应该由「服务器在峰值并发下能否承受」来决定,而不是追求尽可能大的数字。

另外要提醒一点:PBKDF2 不消耗内存,只消耗 CPU 时间。这意味着它在显卡面前抵抗力较弱——显卡可以把大量候选口令并行摊到几千个核心上,迭代次数带来的乘法因子被并行度部分抵消。所以如果追求更强的抗 GPU 能力,应该考虑 Argon2 或 scrypt。

参数变更怎么处理

迭代次数不是设一次就永久不变的。硬件在进步,今天 300 毫秒的计算,五年后可能只要 60 毫秒。

提高迭代次数之后,已有的哈希仍然能校验,但前提是用当初生成时的那组参数。因为 PBKDF2 的输出是裸摘要,不含参数信息,所以这些参数必须自己存下来。

常见的迁移做法是:保留旧参数校验旧数据,在用户下次登录成功时用新参数重新计算并更新存储。这样用户不需要改密码,数据库逐步完成升级。

这也引出了 PBKDF2 使用中最需要注意的一点——参数必须被持久化保存,而且要和哈希值一一对应。后面会专门讨论这个问题。

检查清单

  • 迭代次数是 PBKDF2 唯一的安全旋钮,攻击成本与之成正比
  • OWASP 建议值可作参考:SHA1 用 130 万次、SHA256 用 60 万次、SHA512 用 21 万次
  • 实际部署按目标耗时 100 到 500 毫秒倒推,并在接近生产的硬件上实测
  • 迭代次数过高会让登录接口成为拒绝服务的放大器
  • PBKDF2 只消耗 CPU 时间,抗 GPU 能力弱于 Argon2 与 scrypt
  • 参数需随硬件进步重新评估,用登录时顺带升级的方式迁移
阅读 14