10

我正在使用 rails,我注意到我的 password_digest 对于 2 个用户来说是不同的,除了密码摘要之外的所有其他字段都不同。但是我对两者都使用了相同的密码“abcd”..
它最终生成了这两个不同的哈希值

  1. $2a$10$QyrjMQfjgGIb4ymtdKQXI.WObnWK0/CzR6yfb6tlGJy0CsVWY0GzO
  2. $2a$10$dQSPyeQmZCzVUOXQ3rGtZONX6pwvnKSBRmsLnq1t1CsvdOTAMQlem

我认为 bcrypt gem 仅根据密码字段生成哈希!我错了吗?谢谢 :)

4

2 回答 2

23

您在这里看到的不仅仅是密码哈希,还有很多关于这些字符串中包含的哈希的元数据。就 bcrypt 而言,整个字符串将被视为 bcrypt 哈希。以下是它包括的内容:

$ 是 bcrypt 中的分隔符。

$ 2a $ 是使用的 bcrypt 算法。

10美元是使用的成本因素。这就是为什么 bcrypt 在存储哈希方面非常受欢迎。每个散列都有与之相关的复杂性/成本,您可以将其视为计算机生成此散列所需的速度。这个数字当然是与计算机的速度相关的,所以随着这些年来计算机越来越快,生成成本为 10 的散列所花费的时间将越来越少。所以明年你将成本增加到 11,然后到 12... 13... 等等。这允许您未来的哈希值保持强大,同时保持旧哈希值仍然有效。请注意,如果不重新散列原始字符串,就无法更改散列的成本。

$QyrjMQf... 是盐和哈希的组合。这是一个 base64 编码的字符串。

前 22 个字符是盐。

剩余的字符是与 2a 算法一起使用时的哈希值、10 的成本和给定的盐。使用盐的原因是攻击者无法预先计算 bcrypt 哈希值以避免支付生成它们的成本。

实际上,这是您最初问题的答案:哈希值不同的原因是因为如果它们相同,您就会知道,无论何时您看到 bcrypt 字符串$2a$10$QyrjMQfjgGIb4ymtdKQXI.WObnWK0/CzR6yfb6tlGJy0CsVWY0GzO,您都会知道密码是abcd. 因此,您可以只扫描一个哈希数据库,并通过查找该哈希快速找到所有使用 abcd 密码的用户。

你不能用 bcrypt 做到这一点,因为$2a$10$dQSPyeQmZCzVUOXQ3rGtZONX6pwvnKSBRmsLnq1t1CsvdOTAMQlemis also abcd. 还有很多很多很多的哈希将是bcrypt('abcd'). 这使得扫描数据库以查找 abcd 密码几乎是不可能的。

于 2012-06-24T13:27:54.560 回答
2

bcrypt将盐存储在密码哈希中。

这些是具有两种不同盐的相同密码的两个不同哈希值。

验证密码时,bcrypt 将从哈希字段中读取盐值,然后使用该盐值重新计算哈希值。

于 2012-06-24T13:28:09.567 回答