使用 Node.js 自带的 crypto.scrypt 实现密码加盐
密码加盐是一种增强密码安全性的常见做法。为了代码的简洁,下面通过 crypto.scrypt
的同步写法 crypto.scryptSync
方法来实现密码加盐。
步骤:
- 生成一个随机的盐值(salt):盐值是用来增加密码的复杂性,确保相同的密码在不同用户中产生不同的散列值。
- 使用
crypto.scryptSync
进行加盐哈希计算:通过提供密码、盐值和计算的迭代次数(成本因子)来生成一个安全的密码哈希值。 - 存储盐值和哈希:你需要存储盐值和哈希结果,以便后续用户验证时使用。
代码示例:
import crypto from 'node:crypto';
// 生成随机盐值
function generateSalt(length = 16) {
return crypto.randomBytes(length).toString('hex'); // 生成16字节盐值并转换为十六进制字符串
}
// 使用 scryptSync 进行密码加盐处理
function hashPassword(password, salt) {
const key = crypto.scryptSync(password, salt, 64); // 使用 scryptSync 进行加盐处理,64 是输出的哈希长度
return key.toString('hex'); // 返回哈希值(十六进制表示)
}
// 用户注册时加密密码
const password = 'userpassword123';
const salt = generateSalt(); // 生成盐值
const hashedPassword = hashPassword(password, salt);
console.log('Salt:', salt);
console.log('Hashed Password:', hashedPassword);
// 用户登录时验证密码
function verifyPassword(inputPassword, storedSalt, storedHash) {
const inputHash = hashPassword(inputPassword, storedSalt); // 使用输入的密码和存储的盐值生成哈希
return inputHash === storedHash; // 比较计算出的哈希值与存储的哈希值
}
// 测试验证密码
const isPasswordValid = verifyPassword('userpassword123', salt, hashedPassword);
console.log('Is Password Valid:', isPasswordValid);
代码解释:
generateSalt
:生成一个随机的盐值,默认长度为16字节,并以十六进制字符串表示。hashPassword
:使用crypto.scryptSync
对密码和盐值进行加盐处理,生成固定长度的哈希值(64 字节)。这里的64
是scrypt
算法的输出长度,也可以根据需要调整。verifyPassword
:用于验证用户输入的密码是否与存储的哈希值匹配。通过将用户输入的密码和存储的盐值一起哈希,并与存储的哈希值进行比较来确认。
注意事项:
- 盐值(salt):每个用户应使用不同的盐值,这样即使用户使用相同的密码,也能得到不同的哈希值。
- 哈希长度:
crypto.scryptSync
的第三个参数是输出哈希的长度。通常选择较长的输出(例如 64 字节)以增加安全性。 - 成本因子(iterations):
scryptSync
也允许设置迭代次数来增加计算复杂度,但其默认行为已足够安全。
#全栈开发
分享于 2025-01-09