PBKDF2是通过多次哈希运算将密码和盐值扩展为高强度密钥的函数,前端用它加密本地数据或生成AES密钥;需用Web Crypto API的importKey和deriveKey实现,注意HTTPS环境、唯一盐值、足够迭代次数及浏览器兼容性。

HTML5 本身不直接提供 PBKDF2 功能,真正起作用的是 Web Crypto API 中的 deriveKey() 方法,配合 importKey() 和指定算法参数(如 "PBKDF2")来完成密钥派生。它运行在浏览器安全上下文中,无需第三方库,但需注意兼容性与使用细节。
什么是 PBKDF2?为什么 Web 前端需要它?
PBKDF2(Password-Based Key Derivation Function 2)是一种密钥派生函数,通过多次哈希运算(如 SHA-256)将用户密码和盐值(salt)扩展成高强度加密密钥。它能有效抵御暴力破解和彩虹表攻击。
前端使用 PBKDF2 的典型场景包括:
基本步骤:从密码到加密密钥
使用 Web Crypto API 派生 PBKDF2 密钥共分四步,缺一不可:
立即学习“前端免费学习笔记(深入)”;
-
准备原始密码:用
TextEncoder转为Uint8Array -
导入密码为“原始密钥”:调用
crypto.subtle.importKey("raw", passwordBuffer, {name: "PBKDF2"}, false, ["deriveKey"]) -
提供盐值和参数:盐必须是密码学安全随机数(
crypto.getRandomValues(new Uint8Array(16))),迭代次数建议 ≥ 100,000(如 100000 或 200000) -
派生目标密钥:用
deriveKey()指定输出算法(如"AES-GCM")、密钥长度(如 256 位)、是否可导出等
一个可用的最小示例代码
以下代码派生一个 256 位 AES 密钥(可用于后续加密):
async function deriveAESKey(password, salt) {
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveKey"]
);
return crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 200000,
hash: "SHA-256"
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
}
// 使用示例
const salt = crypto.getRandomValues(new Uint8Array(16));
deriveAESKey("myPass123", salt).then(aesKey => {
console.log("派生成功,密钥已就绪");
});
注意事项与常见坑点
- 必须在安全上下文(HTTPS 或 localhost)中运行,HTTP 站点会静默拒绝 Web Crypto API 调用
- 盐值不能复用:每次派生都应生成新盐,并与密文一起存储(盐本身无需保密)
- 迭代次数要权衡性能与安全:太低易被爆破,太高影响用户体验(尤其低端设备)
-
派生出的密钥默认不可导出(
extractable: false),若需序列化保存,须显式设为true,但要注意导出后需妥善保护 -
IE 完全不支持,Safari 对部分参数较敏感,建议检测
crypto.subtle?.deriveKey是否存在











