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

问题描述

老实说,我已尽力在此处或其他任何地方找到答案。 Bcrypt 文档指出,有两种技术可以对密码进行散列/加盐: 技术 1(在单独的函数调用生成盐和散列):

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

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

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

请注意,这两种技术都达到了相同的最终结果...

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

谢谢!

解决方法

这是许多图书馆的常见实现,他们希望使用更乏味的版本。

  • 他们坚持要求您必须传入运行该函数所需的所有内容
  • 他们抽象了在salt字符串中传递salt和成本以及版本控制的细节

我认为方法签名应该是:

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对两个调用的相同方式。

我不同意任何这种都应该暴露给用户——即使它被设计成一个不透明的斑点(即$2b$15$aXN0aWxsbG92ZXlvdWtn...)。

我认为应该是:

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

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