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是否存在