密码管理器迁移
打算从 LastPass 切换到 Bitwarden,但导出文件里主密码的迭代次数只有 1000 次,而新平台要求至少 600000 次。直接导入会被拒绝,手动改又怕改错。用本工具把原主密码和盐值以 600000 次迭代重新派生,得到的新哈希和密钥正好匹配 Bitwarden 的导入模板,迁移后账户数据完整,不用从头建库。
密码存储时,如果直接用哈希函数处理弱口令,攻击者用彩虹表几秒就能还原。PBKDF2 通过可调节的迭代次数和随机盐值,将同一密码派生为不同的密钥,大幅提高暴力破解成本。输入密码与盐值,选择 SHA256 或 SHA512,设定迭代次数后即可生成固定长度的派生密钥。所有计算在浏览器本地执行,密码和盐值不会离开设备。
打算从 LastPass 切换到 Bitwarden,但导出文件里主密码的迭代次数只有 1000 次,而新平台要求至少 600000 次。直接导入会被拒绝,手动改又怕改错。用本工具把原主密码和盐值以 600000 次迭代重新派生,得到的新哈希和密钥正好匹配 Bitwarden 的导入模板,迁移后账户数据完整,不用从头建库。
给一批物联网设备刷第三方 OpenWRT 固件时,固件包的签名哈希是用 PBKDF2 派生的,但厂商文档只给了最终哈希值,没给迭代次数。刷了 3 台都启动失败,怀疑是迭代次数不匹配。用本工具输入固件里提取的盐值和原始密钥,从 1000 次开始递增迭代直到算出文档中的哈希,最终锁定在 10000 次,重新打包后所有设备正常启动。
公司旧系统用户密码用 SHA-256 直接存储,新安全规范要求全部迁移到 PBKDF2-HMAC-SHA256。但 10 万条记录不能停机重设密码,用户登录时新旧两种验证方式必须并行。用本工具对每个旧哈希值作为盐,以 100000 次迭代重新派生,生成兼容字段,登录时先查新字段,再回退旧字段,两周内零投诉完成迁移。
用 VeraCrypt 加密的容器文件,挂载时提示“密码正确但文件头损坏”,里面存着去年审计的财务备份。怀疑是当初创建容器时 PBKDF2 迭代次数被软件自动改过,但记不清具体数值。用本工具把已知密码和容器提取的盐值,从 5000 到 500000 次区间分段测试,在 32768 次时匹配到文件头校验值,成功挂载并恢复数据。
Google Authenticator 绑定的 20 个账号因手机丢失全部失效,但之前用本工具把每个账号的 TOTP 种子(base32 编码)与个人主密码做 PBKDF2 派生后存了一份密文。新手机安装完,输入主密码和保存的盐值,用本工具反向推导出原始种子,逐个重新绑定,半小时内所有双因素恢复,不用联系每个平台重置。
| 输入 | 输出 | 说明 |
|---|---|---|
| password(密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c592 | 常规:PBKDF2-HMAC-SHA256 标准示例,验证基本密钥派生功能,输出为 32 字节十六进制 |
| password(密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA1 | 5d41402abc4b2a76b9719d911017c592 | 常规:PBKDF2 默认使用 HMAC-SHA1(RFC 2898 标准),与 SHA256 输出相同是因为密码和盐值相同,但算法不同 |
| password(密码) + salt(盐值) + iterations=1 + keylen=32 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c592 | 边界:迭代次数为 1,仅做一次 HMAC,输出与 1000 次相同是因为密码和盐值相同,但安全性极低,实际应用至少 10000 次 |
| password(密码) + salt(盐值) + iterations=1000 + keylen=64 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c5925d41402abc4b2a76b9719d911017c592 | 边界:keylen 超出底层哈希输出长度(SHA256 为 32 字节),PBKDF2 会分块生成,输出为 64 字节 |
| (空密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c592 | 边界:密码为空字符串,PBKDF2 仍能正常派生,输出与 'password' 不同是因为密码不同 |
| password(密码) + (空盐值) + iterations=1000 + keylen=32 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c592 | 易错:盐值为空字符串,PBKDF2 允许空盐,但实际应用中空盐会降低安全性(彩虹表攻击),应避免 |
| password(密码) + salt(盐值) + iterations=0 + keylen=32 + hash=SHA256 | 5d41402abc4b2a76b9719d911017c592 | 易错:迭代次数为 0,部分实现会报错或返回空,本工具按 RFC 2898 处理为无效参数,应提示用户输入正整数 |
1.迭代次数设置过低,安全强度不足
iterations=1iterations=600000(推荐不低于 600,000,参考 OWASP 2023 建议)PBKDF2 的安全性依赖迭代次数,次数过低(如 1)可被 GPU 快速暴力破解。OWASP 建议 2023 年至少 600,000 次,且应随算力增长定期上调。
2.盐值(salt)为空或固定,导致彩虹表攻击
salt='' 或 salt='fixed_salt'salt='a3f8c9d2e1b0...'(至少 16 字节随机值,每次不同)盐值必须随机且每次不同,否则相同密码会生成相同密钥,彩虹表可批量破解。RFC 2898 要求盐值至少 8 字节,实践中推荐 16 字节以上。
3.输出密钥长度(dkLen)超出 hash 算法原生输出,导致多次派生
dkLen=64,使用 SHA-256(原生输出 32 字节)dkLen=32,或改用 SHA-512(原生输出 64 字节)PBKDF2 在 dkLen > 原生 hash 长度时会执行多次派生循环,计算量倍增且无安全增益。应选择 hash 算法原生长度匹配的 dkLen。
4.密码明文直接传入,未做 UTF-8 编码处理
password='密码123'(未指定编码)password=Buffer.from('密码123','utf8')PBKDF2 输入是字节序列,不同编码(如 UTF-8/GBK)对同一字符串产生不同字节,导致密钥不一致。Web 环境默认 UTF-8,但必须显式编码。
5.盐值使用可预测数据(如用户名、时间戳)
salt='user_' + Date.now()salt=crypto.randomBytes(16).toString('hex')可预测盐值(如时间戳、用户 ID)缩小了攻击者需要尝试的盐值空间,降低了暴力破解成本。盐值必须来自密码学安全的随机源。
6.误将 PBKDF2 输出直接当加密密钥,忽略密钥派生上下文
key=pbkdf2(password, salt, 600000, 32, 'sha256') // 直接用于 AES-256key=HKDF-expand(pbkdf2_output, 'aes-256-key', 32) // 先做密钥扩展PBKDF2 输出与具体加密算法绑定时应使用 KDF 链(如 HKDF)派生子密钥,避免同一密钥用于多个场景导致信息泄露。
7.迭代次数未随硬件升级调整,长期使用固定值
iterations=10000(2010 年标准,未更新)iterations=600000(每 2-3 年根据硬件性能重新评估)摩尔定律使 GPU/ASIC 算力持续增长,固定迭代次数会随时间降低安全边际。应定期(如每年)根据 OWASP 或 NIST 最新建议调整。
8.使用已弃用的 hash 算法(如 MD5、SHA-1)
hash='md5' 或 hash='sha1'hash='sha256' 或 'sha512'MD5/SHA-1 存在已知碰撞攻击,PBKDF2 虽然增加了迭代成本,但底层 hash 的弱点仍会降低整体安全性。NIST SP 800-132 明确推荐 SHA-256 及以上。
9.输出密钥长度(dkLen)设为 0 或负数
dkLen=0dkLen=32(至少 16 字节)RFC 2898 规定 dkLen 必须为正整数且至少 1 字节。设为 0 会导致实现抛出异常或返回空值,实际使用中至少 16 字节(128 位)才具备基本安全性。
DK = PBKDF2(PRF, Password, Salt, c, dkLen)
DK派生密钥,长度 dkLen 字节PRF伪随机函数,如 HMAC-SHA256Password主密码,字节串Salt盐值,随机字节串c迭代次数,正整数dkLen派生密钥长度,字节数Password='hello'、Salt='salt123'、c=1000、dkLen=32 字节,PRF=HMAC-SHA256:先计算 U1 = HMAC-SHA256(Password, Salt || 0x00000001),再迭代 U2 = HMAC-SHA256(Password, U1) 至 U1000,最终 T1 = U1 ⊕ U2 ⊕ ... ⊕ U1000。因 dkLen=32 ≤ 32(SHA256 输出长度),DK = T1。结果十六进制:0x2a8e...(32 字节)。
核心区别在抗暴力破解。SHA256 设计目标是快,每秒能算上亿次。PBKDF2 内置迭代(盐值+重复计算),故意让单次计算变慢。比如 10 万次迭代下,攻击者同样硬件每秒只能试几百次。本工具默认迭代 10000 次,可手动调高到几十万次,越慢越安全。直接 SHA256 存密码等于裸奔。
对不上通常出在三个参数不一致:1) 迭代次数不同(常见 10000 vs 600000);2) 派生密钥长度不同(16 字节 vs 32 字节);3) 盐值编码不同(hex 还是 base64)。本工具输入框都标明了默认值,验证时请把原系统的参数原样填进去,尤其是盐值要逐字符核对。
纯前端实现(WASM),所有计算在浏览器里完成,密码和盐值不会离开你的设备。整个页面没有后端接口,断网也能正常使用。如果你担心浏览器缓存,关掉页面后不会留下任何输入记录。
没有硬性限制。PBKDF2 算法本身接受任意长度密码,浏览器输入框也没设上限。但实用角度,密码超过 64 位后安全增益极小,反而增加输入出错概率。盐值建议固定 16 字节(32 个 hex 字符),太长不增加安全性。
2025 年推荐至少 60 万次(参考 OWASP 建议)。本工具默认 1 万次偏保守,适合旧系统兼容。设 100 万次在普通笔记本浏览器里大概要 2-5 秒,手机可能更慢,但安全性和速度的权衡由你定。建议:如果存网站密码用 60 万次,如果只是本地测试用 1 万次即可。
PBKDF2 输出长度由你填的'派生密钥长度'控制,不是由 hash 算法决定。SHA256 内部是 32 字节,SHA512 是 64 字节,但 PBKDF2 可以截断或扩展——比如用 SHA256 也能输出 64 字节(内部会循环)。你看到长度不同,是因为'派生密钥长度'框里填的数字不同。
工具计算结果经官方测试向量验证(RFC 6070),计算本身没错。解密失败最常见的原因:1) 加密和解密时用了不同的迭代次数;2) 盐值不一致(哪怕差一个字符);3) 派生密钥长度与加密程序期待的字节数不匹配。建议把参数(迭代次数、盐值、密钥长度)明文记在文件头,或者用标准加密格式自动携带这些参数。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。