在单独的函数调用上生成 bcrypt salt 和 hash 或自动生成 salt 和 hash 之间有实际区别吗?

Is there a practical difference between generate bcrypt salt and hash on separate function calls or auto-gen a salt and hash?

老实说,我尽力在这里或其他任何地方找到答案。 Bcrypt 文档指出 hash/salt 密码有两种技术: 技术 1(在单独的函数调用上生成盐和散列):

bcrypt.genSalt(saltRounds, function(err, salt) {
    bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
        // Store hash in your password DB.
    });
});

和技术 2(自动生成盐和哈希):

bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
    // Store hash in your password DB.
});

请注意,这两种技术实现相同的最终结果...

如果他们这样做了,为什么我们需要添加额外的代码行? 仅仅是审美偏好吗?或者有什么实际原因吗?

谢谢!

这是许多库中的常见实现,他们希望在这些库中使用更乏味的版本。

  • 他们坚持认为您必须传递 运行 函数
  • 所需的所有内容
  • 并且他们抽象了传递 salt 和 cost 的细节,并在 salt string
  • 中进行了版本控制

我认为方法签名应该是:

bcrypt.HashPassword("hunter2"); //using a default cost

bcrypt.HashPassword("hunter2", 15); //if we want to force a cost

但几乎所有其他 bcrypt 库都会做类似的事情:

String salt = bcrypt.GenerateSalt(); //using a default cost
bcrypt.HashPassword("hunter2", salt);

String salt = bcrypt.GenerateSalt(15); //if we want to for a cost
bcrypt.HashPassword("hunter2", salt);

因为当他们去验证一个散列时内部发生了什么,他们从存储的散列中提取保存的盐字符串:

String salt = GetSaltStringFromSavedHash(savedHash);
bcrypt.HashPassword("hunter2", salt);  

所以他们只是 喜欢 这种以相同方式对两个调用使用 HashPassword 的对称性。

我不同意任何 salt 应该暴露给用户——即使它被设计成不透明的 blob(即 b$aXN0aWxsbG92ZXlvdWtn...)。

我觉得应该是:

HashPassword(password);
HashPassword(password, costFactor);

但这就是我;而我是唯一的。