Salt 必须每个用户都不同且随机生成,它让彩虹表彻底失效。存密文时把 salt 一起存(它不需要保密)。
迭代次数越高越难破解,代价是每次派生都要多花时间。OWASP 对 PBKDF2-SHA256 的建议是 60 万次。
以 PBKDF2-SHA256 为例,耗时是单核现代浏览器的粗略参考。
| 迭代次数 | 典型耗时 | 相对成本 | 评价 |
|---|---|---|---|
| 1 万 | 约 10 ms | 0.1× | ❌ 太低,仅适合极低性能设备 |
| 10 万 | 约 100 ms | 1× | ⚠️ 兼容底线,不建议新系统采用 |
| 31 万 | 约 300 ms | 3.1× | ✅ 实用平衡点 |
| 60 万 | 约 600 ms | 6× | ✅ OWASP 推荐下限 |
| 100 万 | 约 1 s | 10× | ✅ 更硬,登录会略有感知 |
| 500 万 | 约 5 s | 50× | ⚠️ 太慢,影响体验,不如换算法 |
⚠️ 使用提示:① 不要在这里输入你正在使用的真实口令——本工具用于学习与验证参数,请用测试口令;② PBKDF2 只是减慢破解速度,挡不住弱口令:`123456` 配 100 万次迭代依然秒破,口令强度永远是第一位;③ 本工具是可调参数的演示器,不是密码存储方案——生产环境请使用成熟库(Argon2id / bcrypt / scrypt)并把参数写进代码,不要手工拼接;④ Web Crypto 没有 Argon2,如果需要 Argon2id 请在服务端用专业库实现;⑤ 迭代次数要和 salt、结果一起存储,否则以后无法复现同样的派生结果;⑥ 本工具不保存任何输入,刷新即清空。
「把用户口令安全地存起来」这件事,第一步就是把口令派生成一串不可逆的密钥——PBKDF2 就是干这个的。
很多人只听说过它,但从没直观感受过参数的影响。这个工具让它变得可观察:
① 参数全可调:哈希算法、salt、迭代次数、输出长度,一个不落;
② 耗时实时显示:把迭代次数从 10 万调到 100 万,你会亲眼看到时间从 0.1 秒变成 1 秒——这就是「让破解变慢」的实际代价;
③ 相对成本:以 10 万次为基准,告诉你当前配置是几倍;
④ 强度评估条:把迭代次数和哈希算法综合成一个直观的评分,配 SHA-1 会被扣分;
⑤ 随机 salt 一键生成:用密码学安全的随机数,不是 `Math.random()`。
全程在你自己的浏览器里完成,口令不上传、不记录,刷新就没了。
怎么实现:
① 导入:`crypto.subtle.importKey('raw', 口令字节, 'PBKDF2', false, ['deriveBits'])`;
② 派生:`crypto.subtle.deriveBits({ name: 'PBKDF2', salt, iterations, hash }, key, 位数)`。口令先用 `TextEncoder` 转成 UTF-8 字节,保证中文口令也按字节正确参与;
③ 随机 salt:`crypto.getRandomValues()` 生成 16 字节(128 位),来自系统 CSPRNG;
④ 耗时测量:用 `performance.now()` 包住完整的 importKey + deriveBits,反映真实开销(含一次性的密钥导入);
⑤ 强度评估:按迭代次数分档打分(1 万以下 10 分,10 万 35 分,31 万 60 分,60 万 80 分,100 万以上 95 分),使用 SHA-1 时上限压到 50 分;这只是参数强度,不代表口令强度。
它不做:不做口令强度检测、不做 Argon2 / bcrypt / scrypt(Web Crypto 里没有)、不做密码库与存储。
importKey + deriveBits)实现 PBKDF2 口令派生,支持 SHA-1 / 256 / 384 / 512、自定义 salt(可一键随机 16 字节)、迭代次数可调(含 10 万 / 31 万 / 60 万 / 100 万 快捷档)与 128~512 位输出;实时显示实测耗时、相对 10 万次的成本倍数与强度评估条(SHA-1 会扣分);输出 Hex / Base64。非安全上下文给出明确引导。纯本地零依赖,适配黑夜模式。
审核通过后就会展示在留言板上,稍安勿躁~
还没有留言,来抢沙发吧!