bcrypt.js
实现,支持异步处理,适用于Node.js服务端,可调节计算成本以平衡性能与安全,确保用户密码可靠加密。
在开发用户认证系统时,密码安全是重中之重。bcrypt 作为一种专为密码存储设计的哈希算法,已成为现代 Web 应用的首选方案,以下是 JavaScript 中使用 bcrypt 的完整指南。
自适应成本机制
bcrypt 的 cost factor
(计算成本系数)可动态调整哈希计算强度,对抗硬件算力提升,将 cost 设为 12 时,单次哈希需约 300ms,有效减缓暴力破解速度。
内置盐值防御彩虹表
每个密码哈希过程自动生成唯一盐值,避免攻击者使用预计算哈希表破解密码,盐值以 $2a$10$...
格式与哈希结果拼接存储,无需单独保存。
行业权威认可
符合 NIST(美国国家标准技术研究院)和 OWASP(开放 Web 应用安全项目)对密码存储的推荐标准。
根据运行环境选择版本:
# Node.js 环境 npm install bcrypt # 浏览器环境(使用 bcrypt.js,但建议仅在服务端处理敏感操作) npm install bcryptjs
const bcrypt = require('bcrypt'); async function registerUser(username, plainPassword) { const saltRounds = 12; // 安全性/性能平衡点 const hashedPassword = await bcrypt.hash(plainPassword, saltRounds); // 存储到数据库(示例使用 MongoDB 语法) await db.collection('users').insertOne({ username, password: hashedPassword }); }
async function loginUser(username, inputPassword) { const user = await db.collection('users').findOne({ username }); if (!user) throw new Error('用户不存在'); const isMatch = await bcrypt.compare(inputPassword, user.password); if (!isMatch) throw new Error('密码错误'); return user; // 验证通过 }
版本兼容性
node.bcrypt.js
要求 Node.js ≥ 10bcrypt.compare()
时需确保哈希值未被修改(如去除了盐值前缀)性能优化建议
// 可通过预生成盐提升并发处理能力 const salt = await bcrypt.genSalt(saltRounds); const hash = await bcrypt.hash(plainPassword, salt);
避免安全误区
bcrypt.getSalt()
:盐值已包含在哈希结果中Q:bcrypt 哈希后的字符串结构是什么?
示例:$2a$12$3K3VN5X2s1Q4B8z6M6U0Ee
$2a
:算法版本标识 12
:cost 参数 3K3VN5X2s1Q4B8z6M6U0Ee
:前 22 字符为盐值,剩余部分为哈希值Q:如何更新旧密码哈希?
通过提高 cost 值重新哈希:
if (bcrypt.getRounds(existingHash) < 12) { const newHash = await bcrypt.hash(plainPassword, 12); }