BCrypt:如何从我正在散列的字符串中生成盐?

时间:2014-07-18 00:53:44

标签: java encryption hash bcrypt

简短的问题:我不想使用bcrypt随机生成的盐。让我们说我正在哈希的密码是" abcd1234"。在过去的美好时光,盐将是" ab"或" abcd"或者" abcd12",换句话说,salt将是密码的前N个字符,其中N是密码所需的最小长度。那么如何从密码本身生成有效的bcrypt盐?

长问题:我正在使用消息传递系统,换句话说,将在内部发送消息进行身份验证,出于显而易见的原因,我不能在此消息中包含纯文本密码。所以流程应该是这样的:

  • 计算机A以明文
  • 获取密码
  • 计算机A使用bcrypt
  • 对密码进行哈希处理
  • 哈希(即安全)密码在我的内部消息中发送
  • 机器B是具有散列密码数据库的认证机器,它获取消息,现在它必须将它收到的散列密码与数据库中的散列密码进行比较以进行身份​​验证。

但是如果BCrypt不允许我使用从我的纯文本密码派生的盐,我怎么能这样做呢?机器A对任何盐都一无所知。它没有对数据库的任何访问权限。机器B是知道这一点的人。因此,必须有一种方法可以从" abcd1234"中获取我的bcrypt盐。或者bcrypt应该有一个方法:

check(String hashedPasswordWithSaltA, String hashedPasswordWithSaltB);

直截了当地说:机器A获取密码,机器B是具有认证数据库的机器。我不想将明文密码从A传递给B,但看起来像bcrypt迫使我这样做。 :(

2 个答案:

答案 0 :(得分:2)

只需使用哈希密码传输salt即可。对密码进行腌制的要点是,在数据库中,明文中相同的两个密码具有不同的哈希值。如果从密码本身生成此salt,则此逻辑会失效。此外,至于解密目的,您必须以纯文本形式存储salt,您实际上是泄露了一大块用户密码。

TLDR:让Bcrypt为您生成盐。然后用散列密码传输盐。盐并不是秘密。

答案 1 :(得分:1)

实际上有两种方法可以解决这个问题。

1)每个网站都有此问题,因为必须将密码发送到服务器。这通常通过使用加密连接(HTTPS / SSL)来解决。密码只会被加密(双向),传输到machine2(服务器),解密后再散列。

2)您可以使用随机盐在BC机器上散列密码,将其发送到machine2并存储散列。要验证密码,machine1首先必须向machine2询问使用过的salt,然后使用此salt哈希密码,然后将哈希值发送到machine2。 Machine2可以验证密码,因为使用了相同的盐。

我快速查看jBCrypt example,您似乎可以自己生成盐并将其作为参数传递。所以你实际上可以从密码中驱除盐,但这会使盐变得无用,它变成了一个更复杂的哈希函数。