前端:使用crypto-js库的SHA256算法,包含用户注册时使用的邮箱加上自定义的secret key生成盐值,接着使用PBKDF2算法进行加密。最后将加密后的密码传给后端。
import CryptoJS from "crypto-js";
export const encryptPassword = (email: string, password: string): string => {
// 生成盐值
const salt = CryptoJS.SHA256(
email,
import.meta.env.SECRET_KEY
).toString();
// 使用 PBKDF2 进行密码加密
const key = CryptoJS.PBKDF2(password, salt, {
keySize: 256 / 32,
iterations: 600_000, //迭代次数符合OWASP标准
hasher: CryptoJS.algo.SHA256,
});
return key.toString(CryptoJS.enc.Base64);
};
后端:创建用户时,使用bcryptjs库的hash方法对密码进行二次加密,并存入数据库。用户登录时,再用compare方法对密码进行解密。
import * as bcrypt from 'bcryptjs';
export class UsersService {
async create(createUserDto) {
// 生成随机盐
const salt = await bcrypt.genSalt(10);
// 使用生成的盐进行密码哈希
const hashedPassword = await bcrypt.hash(createUserDto.password, salt);
return //略
}
async validatePassword(user, password) {
try {
// 比较原始密码和存储的哈希密码
return await bcrypt.compare(password, user.passwordHash);
} catch (error) {
console.error('Password validation error:', error);
return false;
}
}
}