升级现有的bcrypt哈希轮次数

时间:2017-09-19 08:57:38

标签: node.js bcrypt

我有一个数据库,其中大多数哈希的用例太圆了。我希望将这些升级到更高的回合/迭代次数,希望使用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基本上只是循环,我认为它理论上应该可以更多一些,并将其存回。

1 个答案:

答案 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'
})