【问题标题】:BCrypt: how can I generate a salt from the string I am hashing?BCrypt:如何从我正在散列的字符串中生成盐?
【发布时间】:2014-09-09 01:09:22
【问题描述】:

简短的问题:我不想使用 bcrypt 随机生成的盐。假设我正在散列的密码是“abcd1234”。在过去的好日子里,salt 是“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 迫使我这样做。 :(

【问题讨论】:

  • 这首先破坏了使用盐的目的:两个相同的密码具有相同的盐,因此具有相同的哈希值。此外,由于您必须以纯文本形式存储盐,因此您实际上是在泄露大量用户密码。
  • @Quirliom 我不确定你说的是否有道理。你能澄清一下吗?我的观点是机器 A 获得密码,而机器 B 是拥有数据库的机器。我不想以明文形式将密码从机器 A 传递给机器 B,但看起来 bcrypt 会强迫我这样做。 :(
  • 添加了一个答案来尝试解释。

标签: java encryption hash bcrypt


【解决方案1】:

只需使用散列密码传输盐。加盐密码的目的是为了在数据库中,两个明文相同的密码具有不同的哈希值。如果你从密码本身生成这个盐,这个逻辑就会失败。此外,出于解密目的,您必须以明文形式存储盐,这实际上是在泄露用户密码的一部分。

TLDR:让 Bcrypt 为您生成盐。然后使用散列密码传输盐。盐并不意味着保密。

【讨论】:

  • 这行不通 :( :( :( 为什么?至少jBcrypt 不允许我比较两个散列密码。它只允许我将纯文本与散列进行比较。我可以这里遗漏了一些东西,但是从机器 A 传输 passwordHashed + salt 在进行身份验证时对机器 B 没有任何作用,因为 jBcrypt 需要纯文本:( :( :( (参见jBcrypt 网站)
  • 获取哈希值并自己比较它们(它们应该是相同的字符串,因此 .equals 可以工作)
  • 您错过了机器 A 与机器 B 分开的点,机器 B 具有用于密码的原始 SALT。所以我看到的唯一解决方案是让机器 B 以某种方式将存储的盐发送到机器 A,以便机器 A 可以散列并将散列发送到机器 B 进行身份验证。太糟糕了!我放弃了 pcrypt。太烂了!
  • 如果没有其他方法可以将盐送到机器 A 中,那么您的建议就是唯一的方法。不幸的是,这就是它的工作原理。
  • 我正在使用 PBKDF2。搞砸愚蠢的bcrypt!无论如何感谢您的帮助。 :)
【解决方案2】:

你实际上有两个选择来解决这个问题。

1) 每个网站都有这个问题,因为密码必须发送到服务器。这通常通过使用加密连接 (HTTPS/SSL) 来解决。密码只会被加密(双向)、传输到 machine2(服务器)、解密并随后进行哈希处理。

2) 您可以使用 BCrypt 随机盐对 machine1 上的密码进行哈希处理,将其发送到 machine2 并存储哈希值。为了验证密码,machine1 首先必须向 machine2 询问使用过的 salt,然后用这个 salt 对密码进行哈希处理,然后将哈希发送到 machine2。 Machine2 可以验证密码,因为使用了相同的盐。

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

【讨论】:

  • 我不在乎两个相同的密码在数据库中具有相同的哈希值。我可以忍受这一点。因此我使用的是 PBKDF2。
  • @chrisapotek - 我不确定你的意思,但似乎你想省略盐或使其对所有密码保持不变。这不仅会导致相同密码的哈希值相同,还可以创建一个彩虹表来获取数据库的所有密码。这确实是一个安全问题! PBKDF2 无能为力,BCrpyt 也无能为力。
猜你喜欢
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 2023-04-06
  • 2015-05-23
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多