(这不是链接问题恕我直言的重复,因为这更多的是关于盐和密码之间的差异:两个变量都用于生成哈希)
假设攻击者可以离线访问数据库,其中密码使用 bcrypt 散列(没有添加胡椒)。哈希看起来像:
$2y$10$H0mRpD2XJZDguAzxTehwzunRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
其中盐是:H0mRpD2XJZDguAzxTehwzu哈希是nRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G.
攻击者将无法运行彩虹表来匹配哈希,但她可以使用包含的盐计算常见密码,因此执行:
bcrypt("abcd1234", 10, "H0mRpD2XJZDguAzxTehwzu")
将产生:
nRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
你有!她可以通过所有数据库测试“abcd1234”,并能够在几秒钟/几分钟内识别出哪些用户正在使用该弱密码。
那么如果只有哈希nRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G存储在数据库中(没有盐)呢?
如果攻击者强烈认为用户“abcdefg”可能正在使用密码“abcd1234”,她如何离线测试她的理论?她需要猜盐。她怎么可能做到?有没有比尝试每种组合更简单的方法?也许在那种特定情况下,没有足够的动力去尝试它。但是,如果她怀疑系统对所有密码使用相同的盐(因为某些哈希值是相同的)怎么办?她要破解它有多难?
更新
Peleus 的回答接近我的预期。我将尝试扩展它(如果我错了,请纠正我):
熵:
在 Bcrypt 中,盐通常是 16 个随机字节(128 位)。如果我们将其与相同长度的密码进行比较,那么盐的熵将比密码更大,因为密码通常仅限于用户可以使用键盘键入的内容。
这 16 个字节被编码为 HEX(使用 Base64)并变成 22 个长度。如果我们将它们与 22 个字符的密码进行比较,那么密码将包含更大的熵(因为它可以包含符号和完整的字母表)。
长度:
Bcrypt 盐限制为 16 个字节,而密码可能限制为 72 个字节,具体取决于实现。
碰撞:
2 种不同的盐将生成 2 种不同的哈希值,因此密码也是如此。然而,在某些时候,2 个不同的盐可以使用相同的密码产生相同的哈希值,反之亦然。每种情况的概率是多少?这也许是我应该在 crypto.SE 中问的问题。但我把它留在这里,以防有人知道它的答案。
设计:
该算法旨在保护密码而不是盐。这意味着盐在设计上并不意味着安全,这表明可能有一种方法可以在不强制使用的情况下获得它们。
虚构案例:
我们习惯于使用用户密码方法来保护对系统的访问。但是,如果发生这样的事情怎么办(请告诉我,这只是一个例子)?:
公司CauseWeWantItThatWay使用微芯片存储唯一的 22 位十六进制字符值(用作盐)。每个用户将使用该唯一盐生成总共 5 个密码或 PIN 码(每个 4 位,是的,他们很懒惰)以访问 5 个不同的系统。
现在让我们假设我被分配到其中一个系统,并且我知道其中一个 PIN 码,并且不知何故我可以访问数据库。如果包含盐,那么获得这些 PIN 码将是微不足道的,但是如果没有盐,我将不得不破解它。
我知道你在想什么。该公司的安全实施非常糟糕(他们应该在地狱中燃烧)。此外,他们本可以使用“盐”作为胡椒粉,而让盐随意放置。所以我的问题是,在那种情况下,添加一个 22-hex-chars 作为胡椒和使用那些作为盐是一样的吗?根据 Peleus 的说法,是相同的(因此不存在获取盐的捷径)。
毕竟不是每个人都遵循建议,并且算法允许您设置盐,这使得这种情况完全可能(尽管不太可能也不推荐)。