用于密码散列的非随机盐

更新:我最近从这个问题中得知,在下面的整个讨论中,我(我确信其他人也是)也有点混乱:我一直称之为彩虹表,实际上称为哈希表。 彩虹表是更复杂的生物,实际上是Hellman哈希链的变种。 虽然我相信答案仍然是一样的(因为它不能归结为密码分析),但是有些讨论可能有些偏差。
这个问题:“ 什么是彩虹桌,他们是如何使用的? ”


通常情况下,我总是build议使用密码强的随机值作为盐,与散列函数(例如密码)一起使用,以防止彩虹表攻击。

但是,盐是随机的,它实际上是密码学上必要的吗? 任何独特的价值(唯一的每个用户,例如userId)在这方面就足够了? 它实际上会阻止使用单个彩虹表来破解系统中的所有(或大部分)密码。
但熵的缺乏是否真的削弱了哈希函数的密码强度呢?


请注意,我不是问为什么要使用盐,如何保护它(不需要),使用单个常量散列(不),或使用什么样的散列函数。
盐是否需要熵。


感谢所有答案到目前为止,但我想专注于我(一点)不太熟悉的领域。 密码分析的主要影响 – 我会很感激,如果有人有一些来自encryptionmathPoV的input。
另外,如果还有额外的vector没有被考虑,那也是很好的input(参见@Dave Sherohman指向多个系统)。
除此之外,如果您有任何理论,想法或最佳实践 – 请以证据,攻击情景或经validation据作为背景。 或者甚至是可以接受的权衡的有效考虑…我对这个问题上的最佳实践(资本B资本P)很熟悉,我想certificate这实际上提供了什么价值。


编辑:这里有一些非常好的答案,但我认为@Dave说,它归结为彩虹表的常见用户名称…也可能不太常用的名称。 但是,如果我的用户名是全球唯一的呢? 不一定是我的系统唯一的,但每个用户 – 例如电子邮件地址。
对于单个用户来说,build立RT是没有任何意义的(正如@Dave强调的那样,盐不是保密的),这仍然会阻止集群。 唯一的问题是,我可能会在不同的网站上有相同的电子邮件和密码 – 但盐无论如何不会阻止。
所以,它回到了密码分析 – 熵是必要的,还是不是? (我目前的想法是从密码分析的angular度来看没有必要,但是这是出于其他实际的原因)。

Salt传统上是作为散列密码的前缀存储的。 这已经使任何攻击者都可以访问密码散列。 将用户名用作盐或不影响这些知识,因此对单系统安全性没有影响。

但是,使用用户名或任何其他用户控制的值作为salt会降低跨系统安全性,因为在多个使用相同密码散列algorithm的系统上拥有相同用户名和密码的用户最终会得到相同的密码散列每个系统。 我不认为这是一个重大的责任,因为作为一个攻击者,我会尝试使用目标账户已经在其他系统上使用的密码,然后再尝试任何其他方式破坏账户。 相同的散列只会提前告诉我,已知的密码会起作用,它们不会使实际的攻击变得更容易。 (但请注意,对帐户数据库进行快速比较将提供一个优先级较高的目标列表,因为它会告诉我哪些人是谁以及谁不重复使用密码。)

这个想法面临的更大的危险是用户名通常被重复使用 – 例如,任何你喜欢访问的网站都会有一个名为“Dave”的用户帐户,而“admin”或“root”更为常见 – 这会使以这些通用名称为目标的用户build造彩虹表更容易和更有效。

这两个缺陷都可以通过在密码之前添加第二个盐值(固定和隐藏或像标准盐一样暴露于密码)来有效解决,但是在这一点上,您可能无论如何只是使用标准熵盐用户名的工作。

编辑添加:很多人都在谈论熵,盐中的熵是否重要。 大多数评论似乎都是这样认为的,但并非如此。

一般的想法似乎是,熵是重要的,以便攻击者难以猜测盐。 这是不正确的,实际上是完全不相关的。 正如人们多次指出的那样,受盐影响的攻击只能由拥有密码数据库的人做出,而有密码数据库的人只能看看每个账户的盐是什么。 当你可以轻易地查找时,无论是否可以猜测都无关紧要。

熵重要的原因是为了避免盐值的聚集。 如果salt基于用户名,并且您知道大多数系统将有一个名为“root”或“admin”的帐户,那么您可以为这两种盐制作彩虹表,并且它会破解大多数系统。 另一方面,如果使用随机的16位盐并且随机值大致均匀分布,则对于所有2 ^ 16种可能的盐,您需要一个彩虹表。

这并不是要阻止攻击者知道个人帐户的盐是什么,而是关于不给他们一个单一的盐的大的脂肪目标,将用于大部分潜在的目标。

使用高熵盐对于安全地存储密码是绝对必要的。

以我的用户名'gs'并将其添加到我的密码'MyPassword'给出gsMyPassword。 这很容易用彩虹表破坏,因为如果用户名没有足够的熵,可能是这个值已经存储在彩虹表中,尤其是如果用户名短。

另一个问题是您知道用户参与两项或更多项服务的攻击。 有很多常见的用户名,可能最重要的是admin和root。 如果有人创build了一个含有最普通用户名的盐的彩虹桌,他可以用它来危害账户。

他们曾经有一个12位盐 。 12位是4096个不同的组合。 这样做不够安全,因为现在很多信息可以很容易地存储起来 。 4096最常用的用户名也一样。 很可能有一些用户会select属于最常用用户名的用户名。

我find了这个密码检查器 ,它可以计算出你的密码的熵。 密码熵越小(比如使用用户名)就越容易使用彩虹表,因为它们试图至less覆盖所有低熵密码,因为它们更可能发生。

诚然,单用户名可能是有问题的,因为人们可以在不同的网站之间共享用户名。 但是,如果用户在每个网站上有不同的名字,这应该是没有问题的。 那么为什么不在每个网站上使它独一无二。 像这样散列密码

散列函数( “www.yourpage.com /” +用户名+ “/” +密码)

这应该解决这个问题。 我不是密码分析的主人,但是我确信我们不使用高熵的事实会让哈希值变弱。

我喜欢同时使用:高熵随机每logging盐,加上logging本身的唯一ID。

虽然这并没有增加对字典攻击等的安全性,但是它确实删除了有人将他们的盐和哈希值复制到另一个logging以便用自己的密码replace密码的情况。

(无可否认,在这种情况下很难想象这种情况,但是在安全方面我没有看到带子和大括号的伤害。)

如果盐是已知的或容易猜测的,你没有增加字典攻击的难度。 甚至可以创build一个修改后的彩虹表,将“恒定”的盐考虑在内。

使用独特的盐增加了BULK字典攻击的难度。

具有独特的密码强度的盐值将是理想的。

我会说,只要每个密码的盐都不一样,你可能会好的。 盐的要点是,你不能使用标准的彩虹表来解决数据库中的每一个密码。 所以如果你对每一个密码应用不同的盐(即使不是随机的),攻击者基本上也必须为每个密码计算一个新的彩虹表,因为每个密码使用不同的盐。

使用更多熵的盐并没有太多的帮助,因为在这种情况下攻击者被假定已经拥有数据库。 既然你需要能够重新创build哈希,你必须已经知道盐是什么。 所以你必须把盐或盐中的数值存储在文件中。 在像Linux这样的系统中,获取盐的方法是已知的,所以没有秘密盐的用法。 你必须假设拥有你的散列值的攻击者可能也知道你的salt值。

哈希函数的强度不是由它的input决定的!

使用攻击者已知的盐显然使得构build彩虹表(特别是对于像root这样的硬编码的用户名)更有吸引力,但是它并不削弱散列表 。 使用攻击者未知的盐会使系统更难以攻击。

用户名和密码的连接可能仍然提供了一个智能彩虹表的条目,所以使用一系列伪随机字符的盐,与散列密码一起存储可能是一个更好的主意。 举个例子,如果我有用户名“土豆”和密码“啤酒”,你的散列的连接input是“potatobeer”,这是一个彩虹表的合理入口。

每次用户更改密码时更改盐值可能有助于抵御长时间的攻击,如执行合理的密码策略,例如混合大小写,标点符号,最小长度, n周后更改。

不过,我会说你select的摘要algorithm更重要。 例如,对于生成彩虹表的人来说,使用SHA-512将比MD5更为痛苦。

盐应尽可能多地熵,以确保如果一个给定的input值被多次散列,所得到的散列值将尽可能接近,总是不同的。

在salt中使用不断变化的salt值和尽可能多的熵将确保散列(比如password + salt)的可能性会产生完全不同的散列值。

盐中的熵越小,生成相同盐值的机会就越多,因此生成相同哈希值的机会就越大。

散列值的性质在input已知时是“常量”,而“常量”是允许字典攻击或彩虹表如此有效。 通过尽可能多地改变所得到的散列值(通过使用高熵盐值)确保对相同的input+随机盐进行散列将产生许多不同的散列值结果,从而破坏(或者至less大大降低了彩虹表的有效性)攻击。

熵是Salt价值的一点。

如果盐背后有一些简单的,可重现的“math”,那么盐就不存在了。 只是增加时间值应该没问题。