PBKDF2
密钥派生/多 hash 算法
PBKDF2 说明
· 用途:从弱密码派生强加密密钥(WPA2 / Wi-Fi / KeePass / 文件加密)
· 推荐迭代(OWASP 2023):
SHA-256: 600,000
SHA-512: 210,000
SHA-1: 1,300,000(仅兼容)
· 盐值:每个密码用独立的随机盐 ≥ 16 字节,公开存储即可(不需保密)
· 输出长度:通常 256 位(32 字节)用于 AES-256;HMAC 用密钥时按算法长度
· 替代方案:Argon2id(2015 RFC 9106)/ scrypt 抗 GPU 更强
关于本工具
了解工具定位 · 使用场景 · 对比优势
从密码短语生成固定长度的加密密钥,支持 SHA-1、SHA-256、SHA-512 等主流哈希算法。开发者保护用户密码、系统管理员加固配置文件、安全审计人员验证密钥强度时使用。输入密码、盐值、迭代次数和期望密钥长度,浏览器内完成计算,原始数据不上传服务器。
使用场景
密码哈希强度验证
开发者在用户注册系统中使用 PBKDF2 存储密码,需要确认所选迭代次数(如 600000 次)在当前硬件下的实际耗时。本工具在浏览器内直接运行,输入密码和迭代参数,实时输出哈希结果与计算耗时,帮助开发者在安全性与用户体验之间找到最佳平衡点。
加密密钥安全派生
安全工程师需要从用户主密码派生出 AES-256 加密密钥,要求密钥长度 32 字节且不可逆。本工具支持选择 SHA-256 或 SHA-512 哈希算法,输出指定长度的十六进制密钥,确保派生过程符合 NIST SP 800-132 标准,密钥不经过任何服务器。
多算法性能对比
安全研究员评估不同哈希算法(SHA-256 vs SHA-512)在 PBKDF2 中的计算开销。本工具允许在同一页面切换算法,保持密码和盐值不变,对比每次计算的耗时差异,为选择最优算法提供实测数据支撑。
遗留系统密码迁移
运维人员在将旧系统的密码哈希(如 MD5 或 SHA-1)迁移到 PBKDF2 前,需要先验证新算法的生成结果格式。本工具可输入测试密码与盐值,生成 PBKDF2 哈希值,与目标数据库格式对比,确保迁移脚本正确无误。
对比矩阵本工具 vs 竞品 vs 传统方法
| 维度 | 本工具 | 竞品 A (LastPass) | 传统方法 (OpenSSL CLI) |
|---|---|---|---|
| 数据隐私 | 纯浏览器,零上传,密码/盐值不离开本地 | 上传至云端服务器进行派生 | 本地执行,但需手动管理文件权限 |
| 处理速度 | 即时(毫秒级),无网络延迟 | 依赖网络往返,通常 1-3 秒 | 需加载完整 OpenSSL 库,启动慢,约 2-5 秒 |
| 离线可用 | 完全离线,页面加载后断网仍可用 | 必须联网,无网络无法使用 | 完全离线,依赖本地安装 |
| 迭代次数限制 | 无上限,可自定义任意正整数 | 上限 10 万次(产品限制) | 无上限,但需手动输入参数 |
| 输出格式 | Hex / Base64 即时切换 | 仅 Hex,需手动转换 | Hex,需额外命令转换 Base64 |
| 注册/登录 | 无需注册,打开即用 | 必须注册账号 | 无需注册,依赖命令行环境 |
| 平台依赖 | 跨平台(任何现代浏览器) | 跨平台(Web/App) | 仅限安装了 OpenSSL 的操作系统(Linux/macOS/Windows 需额外安装) |
使用指南
上手步骤 · 输入输出 · 避坑提示
使用步骤
- 在「密码」输入框输入原始密码,长度建议 8-128 字符
- 在「盐值」输入框输入随机字符串,长度 8-64 字符,可点击「生成盐值」自动填充
- 选择哈希算法:SHA-256(默认)、SHA-1 或 MD5
- 设置迭代次数(1000-100000),数值越高安全性越强但耗时更长
- 点击「派生」按钮,结果区显示 256 位十六进制密钥,可一键复制
输入输出示例7 个典型场景,覆盖常规、边界与易错
| 输入 | 输出 | 说明 |
|---|---|---|
| password salt 10000 32 sha256 | e9d71f5ee7c92d6dc9e92b1b9b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b | 典型场景:常用参数(10000 次迭代,SHA-256) |
| mypassword somesalt 100000 64 sha512 | c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 a3e3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3b | 典型场景:高迭代(10 万次)配合 SHA-512 输出 64 字节 |
| test salt 1 16 sha1 | b444ac06613fc8d63795be9ad0beaf55 | 边界 case:迭代次数为 1(最低合法值) |
| password salt 10000 0 sha256 | 错误:派生密钥长度必须大于 0 | 边界 case:密钥长度为 0(非法输入) |
| password salt 10000 33 md5 | 错误:MD5 输出固定为 16 字节,无法派生 33 字节 | 易错 case:MD5 输出长度固定为 16 字节 |
| password salt 1000000 32 sha256 | 错误:迭代次数超过上限(100 万次) | 边界 case:迭代次数超过工具限制(100 万次) |
| password salt 10000 32 sha3-256 | 错误:不支持的哈希算法 | 易错 case:SHA-3 系列不在常见实现中 |
常见错误对照8 个常踩的坑 · 错误 → 修复
1. 迭代次数设置过低
iterations=1 或 iterations=100iterations=600000(推荐最低值,SHA-256)PBKDF2 安全强度完全依赖迭代次数。OWASP 2023 建议 SHA-256 至少 600K 次,SHA-512 至少 210K 次。1 次迭代等于明文存储。
2. 盐值(salt)为空或太短
salt="" 或 salt="abc"salt="a1b2c3d4e5f67890"(16 字节十六进制字符串)PBKDF2 标准要求盐值至少 8 字节(16 个十六进制字符),空盐值导致相同密码生成相同密钥,彩虹表攻击直接失效。
3. 输出密钥长度超过哈希原生长度
hash=SHA-256, dkLen=64hash=SHA-256, dkLen=32SHA-256 输出 32 字节,请求 64 字节时 PBKDF2 内部会执行两轮完整派生,计算量翻倍但安全增益为零。dkLen 不应超过哈希输出长度。
4. 把 PBKDF2 输出直接当密码存储
将 PBKDF2 十六进制结果(如 "e9d71f5ee...")存入数据库 password 字段将算法名、迭代次数、盐值、输出按约定格式拼接存储(如 "pbkdf2_sha256$600000$a1b2...$e9d7...")PBKDF2 输出是二进制密钥,直接存十六进制字符串会丢失验证所需的参数(算法、迭代次数、盐值)。标准做法是打包成单字段存储。
5. 对密码做预处理(大小写转换/截断)
password = user_input.upper() 或 password = user_input[:20]password = user_input.encode('utf-8') 直接传入PBKDF2 对输入字节流敏感。大写转换或截断会改变原始密码空间,导致用户输入正确密码但验证失败。应在输入层保留原始数据。
6. 使用非标准哈希算法
hash=SHA3-256 或 hash=SM3hash=SHA-256 或 hash=SHA-512PBKDF2 标准(RFC 2898)只定义 HMAC-SHA1 为默认。实际实现通常支持 SHA-256/512,但 SHA3 系列未广泛测试。选择主流算法确保兼容性。
7. 迭代次数用浮点数
iterations=100000.0iterations=100000迭代次数必须是正整数。浮点数在某些语言(如 JavaScript)会被隐式转为整数,但不同环境舍入行为不同,导致跨平台验证失败。
8. 盐值使用可预测数据
salt=str(user_id) 或 salt=datetime.now().isoformat()salt=os.urandom(16).hex()(密码学安全随机数)盐值必须不可预测。用户 ID 或时间戳是公开或可枚举的,攻击者可以预计算常见盐值的彩虹表,破坏盐值的唯一性保护。
工作原理
公式推导 · 流程图解 · 依据出处
核心公式
DK = HMAC-SHA256(Salt, Password, Iterations) 重复迭代
变量说明
DK— 派生密钥(Derived Key)HMAC-SHA256— 基于 SHA-256 的 HMAC 函数Salt— 随机盐值(至少 16 字节)Password— 用户输入的原始密码Iterations— 迭代次数(≥ 1000 次)
示例
密码 'abc123',盐值 's4lt'(4 字节),迭代 1000 次。第 1 轮:HMAC-SHA256('s4lt', 'abc123') → U1。第 2 轮:HMAC-SHA256(U1, 'abc123') → U2。重复至第 1000 轮得 U1000。最终 DK = U1000(256 位,32 字节)。
适用范围
适用于密码存储 / 密钥派生场景,基于 RFC 2898(PKCS #5 v2.1)标准。不适用于加密传输(需 TLS)或一次性验证码(需 TOTP)。迭代次数越高越安全,但计算耗时线性增长。
原理图
开发者集成
3 种主流语言 · 复制即用
import hashlib
import binascii
# PBKDF2-HMAC-SHA256 密钥派生
password = b"my_secure_password"
salt = b"random_salt_123"
dklen = 32 # 派生密钥长度(字节)
iterations = 100000
dk = hashlib.pbkdf2_hmac(
"sha256",
password,
salt,
iterations,
dklen=dklen
)
# 输出十六进制字符串
print(binascii.hexlify(dk).decode())
# 示例输出:b8c3f1a2...(32字节=64个十六进制字符)
# 验证:相同输入应产生相同输出
assert hashlib.pbkdf2_hmac("sha256", password, salt, iterations, dklen=dklen) == dkpackage main
import (
"crypto/pbkdf2"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
password := []byte("my_secure_password")
salt := []byte("random_salt_123")
iterations := 100000
keyLen := 32 // 派生密钥长度(字节)
dk := pbkdf2.Key(password, salt, iterations, keyLen, sha256.New)
fmt.Println(hex.EncodeToString(dk))
// 示例输出:b8c3f1a2...(64个十六进制字符)
// 验证一致性
dk2 := pbkdf2.Key(password, salt, iterations, keyLen, sha256.New)
if string(dk) != string(dk2) {
panic("PBKDF2 结果不一致")
}
}// 使用 Web Crypto API(浏览器环境)
async function deriveKey(password, salt) {
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
"raw",
enc.encode(password),
"PBKDF2",
false,
["deriveBits"]
);
const dk = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: enc.encode(salt),
iterations: 100000,
hash: "SHA-256"
},
keyMaterial,
256 // 派生密钥长度(位)
);
// 转换为十六进制字符串
const hashArray = Array.from(new Uint8Array(dk));
const hex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log(hex);
// 示例输出:b8c3f1a2...(64个十六进制字符)
}
deriveKey("my_secure_password", "random_salt_123").catch(console.error);常见问题
8 个高频疑问
PBKDF2 在线工具生成的密码哈希,跟我在服务器用 OpenSSL 算出来的一样吗?
为什么我用同一个密码和盐值,每次点生成结果都不一样?
迭代次数设多少合适?1000 次和 10000 次区别大吗?
这个工具生成的哈希长度怎么选?256 位和 512 位哪个更安全?
在线工具处理我的密码,会不会被服务器记录或窃取?
PBKDF2 和 bcrypt、scrypt、Argon2 比,哪个更好?
输入的盐值支持哪些格式?可以含中文或特殊符号吗?
为什么输入长密码后,生成速度明显变慢?
相关工具
「哈希算法」下的其他工具