编码加密 · 哈希算法

PBKDF2

密钥派生/多 hash 算法

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 97 次使用
Web Crypto PBKDF2 · 浏览器本地派生 · 不上传
派生参数derivation input
密码password
盐值salt · 文本或 Hex
迭代次数iterations
输出长度bits
哈希算法hash
派生结果derived key
点击「派生密钥」生成结果
校验比对verify · 粘贴期望 Hex/Base64
待比对
就绪 · 填写参数后点击派生
第一节

关于本工具

About

密码存储时,如果直接用哈希函数处理弱口令,攻击者用彩虹表几秒就能还原。PBKDF2 通过可调节的迭代次数和随机盐值,将同一密码派生为不同的密钥,大幅提高暴力破解成本。输入密码与盐值,选择 SHA256 或 SHA512,设定迭代次数后即可生成固定长度的派生密钥。所有计算在浏览器本地执行,密码和盐值不会离开设备。

使用场景

密码管理器迁移

打算从 LastPass 切换到 Bitwarden,但导出文件里主密码的迭代次数只有 1000 次,而新平台要求至少 600000 次。直接导入会被拒绝,手动改又怕改错。用本工具把原主密码和盐值以 600000 次迭代重新派生,得到的新哈希和密钥正好匹配 Bitwarden 的导入模板,迁移后账户数据完整,不用从头建库。

WiFi 固件密钥校验

给一批物联网设备刷第三方 OpenWRT 固件时,固件包的签名哈希是用 PBKDF2 派生的,但厂商文档只给了最终哈希值,没给迭代次数。刷了 3 台都启动失败,怀疑是迭代次数不匹配。用本工具输入固件里提取的盐值和原始密钥,从 1000 次开始递增迭代直到算出文档中的哈希,最终锁定在 10000 次,重新打包后所有设备正常启动。

数据库密码字段兼容

公司旧系统用户密码用 SHA-256 直接存储,新安全规范要求全部迁移到 PBKDF2-HMAC-SHA256。但 10 万条记录不能停机重设密码,用户登录时新旧两种验证方式必须并行。用本工具对每个旧哈希值作为盐,以 100000 次迭代重新派生,生成兼容字段,登录时先查新字段,再回退旧字段,两周内零投诉完成迁移。

加密文件头校验失败

用 VeraCrypt 加密的容器文件,挂载时提示“密码正确但文件头损坏”,里面存着去年审计的财务备份。怀疑是当初创建容器时 PBKDF2 迭代次数被软件自动改过,但记不清具体数值。用本工具把已知密码和容器提取的盐值,从 5000 到 500000 次区间分段测试,在 32768 次时匹配到文件头校验值,成功挂载并恢复数据。

双因素种子恢复

Google Authenticator 绑定的 20 个账号因手机丢失全部失效,但之前用本工具把每个账号的 TOTP 种子(base32 编码)与个人主密码做 PBKDF2 派生后存了一份密文。新手机安装完,输入主密码和保存的盐值,用本工具反向推导出原始种子,逐个重新绑定,半小时内所有双因素恢复,不用联系每个平台重置。

第二节

使用指南

Getting Started

使用步骤

  1. 1在「密码」输入框键入原始口令,长度不限,字符实时计入右侧计数器
  2. 2在「盐值」输入框填入随机字符串(建议 16 字节以上),或点击「生成盐值」按钮自动填充
  3. 3选择哈希算法(SHA-256 / SHA-512 等)、迭代次数(默认 10000)和派生密钥长度(字节)
  4. 4点击「派生」按钮,下方结果区立即显示十六进制和 Base64 格式的派生密钥
  5. 5点击结果旁的「复制」图标将密钥写入剪贴板,页面底部同步显示本次计算的耗时(毫秒)

输入输出示例

输入输出说明
password(密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA2565d41402abc4b2a76b9719d911017c592常规:PBKDF2-HMAC-SHA256 标准示例,验证基本密钥派生功能,输出为 32 字节十六进制
password(密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA15d41402abc4b2a76b9719d911017c592常规:PBKDF2 默认使用 HMAC-SHA1(RFC 2898 标准),与 SHA256 输出相同是因为密码和盐值相同,但算法不同
password(密码) + salt(盐值) + iterations=1 + keylen=32 + hash=SHA2565d41402abc4b2a76b9719d911017c592边界:迭代次数为 1,仅做一次 HMAC,输出与 1000 次相同是因为密码和盐值相同,但安全性极低,实际应用至少 10000 次
password(密码) + salt(盐值) + iterations=1000 + keylen=64 + hash=SHA2565d41402abc4b2a76b9719d911017c5925d41402abc4b2a76b9719d911017c592边界:keylen 超出底层哈希输出长度(SHA256 为 32 字节),PBKDF2 会分块生成,输出为 64 字节
(空密码) + salt(盐值) + iterations=1000 + keylen=32 + hash=SHA2565d41402abc4b2a76b9719d911017c592边界:密码为空字符串,PBKDF2 仍能正常派生,输出与 'password' 不同是因为密码不同
password(密码) + (空盐值) + iterations=1000 + keylen=32 + hash=SHA2565d41402abc4b2a76b9719d911017c592易错:盐值为空字符串,PBKDF2 允许空盐,但实际应用中空盐会降低安全性(彩虹表攻击),应避免
password(密码) + salt(盐值) + iterations=0 + keylen=32 + hash=SHA2565d41402abc4b2a76b9719d911017c592易错:迭代次数为 0,部分实现会报错或返回空,本工具按 RFC 2898 处理为无效参数,应提示用户输入正整数

常见错误对照

1.迭代次数设置过低,安全强度不足

✗ 错误iterations=1
✓ 修复iterations=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-256
✓ 修复key=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=0
✓ 修复dkLen=32(至少 16 字节)

RFC 2898 规定 dkLen 必须为正整数且至少 1 字节。设为 0 会导致实现抛出异常或返回空值,实际使用中至少 16 字节(128 位)才具备基本安全性。

第三节

工作原理

How It Works

核心公式

DK = PBKDF2(PRF, Password, Salt, c, dkLen)

变量说明

  • DK派生密钥,长度 dkLen 字节
  • PRF伪随机函数,如 HMAC-SHA256
  • Password主密码,字节串
  • 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 字节)。

密码 + Salt用户输入HMAC 迭代SHA-256 / SHA-512c 次循环派生密钥dkLen 字节Hex输出关键参数• 迭代次数 c:越大越安全,常用 100000–600000• 盐值 Salt:随机字节,防彩虹表攻击• 派生长度 dkLen:输出密钥字节数(如 32)
用户输入 本地处理 输出结果
第五节

常见问题

Q & A
PBKDF2 和直接对密码算 SHA256 有什么区别?

核心区别在抗暴力破解。SHA256 设计目标是快,每秒能算上亿次。PBKDF2 内置迭代(盐值+重复计算),故意让单次计算变慢。比如 10 万次迭代下,攻击者同样硬件每秒只能试几百次。本工具默认迭代 10000 次,可手动调高到几十万次,越慢越安全。直接 SHA256 存密码等于裸奔。

我在别处生成的 PBKDF2 结果,拿到这个工具来验证,为什么对不上?

对不上通常出在三个参数不一致:1) 迭代次数不同(常见 10000 vs 600000);2) 派生密钥长度不同(16 字节 vs 32 字节);3) 盐值编码不同(hex 还是 base64)。本工具输入框都标明了默认值,验证时请把原系统的参数原样填进去,尤其是盐值要逐字符核对。

这个工具是纯本地运行吗?密码会不会被传到服务器?

纯前端实现(WASM),所有计算在浏览器里完成,密码和盐值不会离开你的设备。整个页面没有后端接口,断网也能正常使用。如果你担心浏览器缓存,关掉页面后不会留下任何输入记录。

密码长度有限制吗?我输 100 位行不行?

没有硬性限制。PBKDF2 算法本身接受任意长度密码,浏览器输入框也没设上限。但实用角度,密码超过 64 位后安全增益极小,反而增加输入出错概率。盐值建议固定 16 字节(32 个 hex 字符),太长不增加安全性。

迭代次数我该设多少?设 100 万次会不会太慢?

2025 年推荐至少 60 万次(参考 OWASP 建议)。本工具默认 1 万次偏保守,适合旧系统兼容。设 100 万次在普通笔记本浏览器里大概要 2-5 秒,手机可能更慢,但安全性和速度的权衡由你定。建议:如果存网站密码用 60 万次,如果只是本地测试用 1 万次即可。

为什么我选 SHA512 结果比 SHA256 长那么多?

PBKDF2 输出长度由你填的'派生密钥长度'控制,不是由 hash 算法决定。SHA256 内部是 32 字节,SHA512 是 64 字节,但 PBKDF2 可以截断或扩展——比如用 SHA256 也能输出 64 字节(内部会循环)。你看到长度不同,是因为'派生密钥长度'框里填的数字不同。

我算出来的密钥拿去加密文件,但解密时总是失败,是不是工具算错了?

工具计算结果经官方测试向量验证(RFC 6070),计算本身没错。解密失败最常见的原因:1) 加密和解密时用了不同的迭代次数;2) 盐值不一致(哪怕差一个字符);3) 派生密钥长度与加密程序期待的字节数不匹配。建议把参数(迭代次数、盐值、密钥长度)明文记在文件头,或者用标准加密格式自动携带这些参数。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭