分享个人 Full-Stack JavaScript 项目开发经验
在对用户密码加密使用的哈希算法中,pbkdf2 在设计上可以故意放慢速度,增加攻击者破解的难度。它也是 node.js 自带的 crypto 库所支持的算法,我们可以利用它来对用户密码进行加密保护。
下面介绍利用 pbkdf2 算法对用户密码进行加密和比对,并将其封装成一个模块使用:
const crypto = require('crypto');
function pbkdf2_encrypt(password) {
// 生成长度为 32 个字节的盐
const salt = crypto.randomBytes(32);
// 生成长度为 512 个字节的 PBKDF2 哈希值
const hash = crypto.pbkdf2Sync(
// 用户密码
password,
// 盐值
salt,
// 迭代次数(应用哈希函数的次数)
5000,
// 生成密钥的长度
512,
// 摘要函数,通过 crypto.getHashes() 查看支持的摘要函数
'sha256'
);
return {salt, hash};
}
function pbkdf2_compare(password, db_salt, db_hash) {
const hash = crypto.pbkdf2Sync(
password,
db_salt,
5000,
512,
'sha256'
);
return hash.toString('hex') === db_hash.toString('hex');
}
module.exports = {pbkdf2_encrypt, pbkdf2_compare};
在 pbkdf2_encrypt 方法中,我们可以获得加密过程中使用的盐值和计算得出的哈希值,它们是 Buffer 类型数据。我们可以将盐值和结果哈希值分别保存在 MySQL 数据库中的 tinyblob 和 blob 数据类型的字段中。这样,即使数据库被攻击,攻击者也必须使用对应的盐值,重新计算比对的哈希值。在目前安全的迭代次数下,我们可以认为用户的密码是安全的。