我有一个数据库,其中大多数哈希的用例太圆了。我希望将这些升级到更高的回合/迭代次数,希望使用node.bcrypt.js库。
示例:
我的数据库中有这样的东西
'$2a$05$Ss068.p/.i4IRzrYoLM/U.ETLpzwrBs2vVfViqgfC5bI4i3BGClZC'
//From: bcrypt.hashSync("hello world", 5)
我希望它能成为这样的东西:
'$2a$10$6sZOFUEWdVMHoCsgF0k1..RhwoD7VmLlLc5.67/Qw81/XuSuNIOcO'
//From: bcrypt.hashSync("hello world", 10)
有没有办法实现这个目标?我认为api可能看起来像这样:
//Non-existing api;
var hash = '$2a$05$Ss068.p/.i4IRzrYoLM/U.ETLpzwrBs2vVfViqgfC5bI4i3BGClZC';
const roundCount = 10
bcrypt.upgradeHashRoundCount(hash, roundCount)
.then(function(upgradedHash){
console.log(upgradedHash)
})
.catch(function(error){
console.error("Not a bcrypt hash, or has higher round-count than provided round count")
})
编辑以澄清:
我想做一个批处理作业,在那里我获取所有哈希值,并对每个哈希值进行升级,而不提供原始密码。由于bcrypt基本上只是循环,我认为它理论上应该可以更多一些,并将其存回。
答案 0 :(得分:4)
我想到了几种方法。关于bcrypt的好处是圆形存储在盐本身中,因此彼此独立。意思是,您可以顺利过渡而不会破坏旧密码。
所以有两个建议:
您可以开始为更改的所有新密码/密码使用更高的盐。专家显然是你只需要完成哈希轮就完成了。 Con是它可能需要永远,直到所有密码都存储更高的轮次。
如果他们的轮次数较少,您可以在每次成功登录时更新密码。您可以使用getRounds(hash)
。这样您的密码就会很快更新(一旦成功使用一次)
function checkPw(pw, user) {
return bcrypt.compare(pw, user.hash)
.then(success => {
if(success && bcrypt.getRounds(hash) < 10) {
return updateHash(pw, user).then(() => success);
}
return success;
})
}
function updateHash(pw, user) {
return bcrypt.hash(pw, 10).then((newHash) => {
user.hash = newHash;
// update user in db
return user.save();
});
}
checkPw('abc', {
id: 123,
hash: '$2a$04$7AiVQRTAEPWFwldS7CB6VuQcMSenrPlpoEEGdMyQDE8BxcxcJXPgG'
})