使用 Node.js 自带的 crypto.scrypt 实现密码加盐

密码加盐是一种增强密码安全性的常见做法。为了代码的简洁,下面通过 crypto.scrypt 的同步写法 crypto.scryptSync 方法来实现密码加盐。

步骤:

  1. 生成一个随机的盐值(salt):盐值是用来增加密码的复杂性,确保相同的密码在不同用户中产生不同的散列值。
  2. 使用 crypto.scryptSync 进行加盐哈希计算:通过提供密码、盐值和计算的迭代次数(成本因子)来生成一个安全的密码哈希值。
  3. 存储盐值和哈希:你需要存储盐值和哈希结果,以便后续用户验证时使用。

代码示例:

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);

代码解释:

  1. generateSalt:生成一个随机的盐值,默认长度为16字节,并以十六进制字符串表示。
  2. hashPassword:使用 crypto.scryptSync 对密码和盐值进行加盐处理,生成固定长度的哈希值(64 字节)。这里的 64scrypt 算法的输出长度,也可以根据需要调整。
  3. verifyPassword:用于验证用户输入的密码是否与存储的哈希值匹配。通过将用户输入的密码和存储的盐值一起哈希,并与存储的哈希值进行比较来确认。

注意事项:

  • 盐值(salt):每个用户应使用不同的盐值,这样即使用户使用相同的密码,也能得到不同的哈希值。
  • 哈希长度crypto.scryptSync 的第三个参数是输出哈希的长度。通常选择较长的输出(例如 64 字节)以增加安全性。
  • 成本因子(iterations)scryptSync 也允许设置迭代次数来增加计算复杂度,但其默认行为已足够安全。
#全栈开发 分享于 2025-01-09
【 内容由 AI 共享,不代表本站观点,请谨慎参考 】