2009-02-11 113 views
81

更新:我最近从this question了解到,在下面的整个讨论中,我(我相信其他人却太)是一个有点混乱:我把什么叫彩虹表,实际上是在称为哈希表。彩虹表是更复杂的生物,实际上是Hellman Hash Chains的变种。虽然我相信答案仍然是一样的(因为它不归结为密码分析),但一些讨论可能有点偏差。
的问题:“What are rainbow tables and how are they used?密码的非随机盐哈希


通常,我总是建议使用密码强随机值作为盐,为与散列函数(例如,用于密码),例如,以防止彩虹表攻击中使用。

但它实际上是加密必需的盐是随机的?在这方面,任何唯一值(每个用户唯一,例如userId)是否足够?这实际上将阻止使用单一的彩虹表破解所有(或大多数)密码系统...
但确实缺乏熵的真正削弱的散列函数的加密强度?


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


感谢所有迄今为止的答案,但我想专注于我(一点)不太熟悉的领域。密码分析的主要含义 - 如果有人从加密数学PoV中获得一些输入,我会非常感激。
另外,如果还有其他向量没有考虑到,那也是很好的输入(请参阅@Dave Sherohman指向多个系统)。
除此之外,如果您有任何理论,想法或最佳实践 - 请通过证明,攻击场景或经验证据来支持这一点。或者甚至可以考虑可接受的权衡......我对这个主题的最佳实践(大写B资本P)很熟悉,我想证明这实际上提供了什么样的价值。


编辑:这里一些很好的答案,但我认为,作为@戴夫说,它归结为彩虹表,共同的用户名...并可能不太常见的名字了。但是,如果我的用户名是全球唯一的呢?对我的系统不一定是唯一的,但每个用户 - 例如电子邮件地址。
没有激励为单个用户构建RT(如@Dave所强调的,盐不会保密),这仍然会阻止集群。唯一的问题是,我可能在不同的网站上有相同的电子邮件和密码 - 但盐无论如何不会阻止。所以,它回归到密码分析 - 熵是必要的,还是不是? (我现在的想法是这不是从一个密码分析点必要的,但它是从其他实际原因。)

+0

我必须说我很困惑下面的许多答案。使用盐的主要目的是防止彩虹桌攻击,因此任何用户独有的东西都应该这样做,因为它会迫使攻击者为每个盐重新创建一个彩虹桌。我的2c。 – Goran 2009-02-11 13:31:56

回答

146

传统上,salt被存储为哈希密码的前缀。这已经让任何有权访问密码哈希的攻击者知道。将用户名用作盐或不影响这些知识,因此它对单系统安全性没有影响。

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

这个想法的更大危险是用户名通常会被重复使用 - 例如,任何你喜欢访问的网站都会有一个名为“Dave”的用户帐户,而“admin”或“root”更常见 - 这将使彩虹表的构建针对用户这些通用名称更容易和更有效。

这两个缺陷都可以通过在密码之前添加第二个salt值(固定和隐藏或暴露像标准盐)到密码之前有效解决,但是在那个时候,您可能只是使用标准无论如何,不​​要将用户名加入其中。

修改为添加:很多人都在谈论熵和盐中的熵是否重要。这是,但不是因为它的大多数评论似乎认为。

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

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

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

-1

熵是盐值的点。

如果有一些简单的和可重复的“数学”背后的盐,比它的同为盐是不存在的。只是增加时间值应该没问题。

+0

我不明白这个评论。你说“使用熵”,然后:“使用时间”?? – 2009-02-11 12:46:41

+0

如果用户名用于盐,它'不够熵。但是,如果您使用用户名+当前日期 - 这是因为很难猜测何时创建了盐。 – dmajkic 2009-02-11 13:29:49

+0

“足够熵”是主观的;这是你的标准。按时准确计算此值可能不够。 – 2009-02-11 13:44:03

3

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

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

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

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

但是,我会说你选择的摘要算法更重要。例如,对于生成彩虹表的人而言,使用SHA-512将比MD5更令人痛苦。

+0

力量的功能不会改变,但输出肯定会改变。如果输入可以被影响或已知,那么或许可以推导出散列值。这是风险。 – 2009-02-11 12:49:45

+0

@Martin:如果你有没有匹配,你应该能够从哈希值中推断出唯一的东西!将“roota”或“rootb”(其中“a”和“b”代表密码)放入散列函数会给您提供完全不同的输出。 – 2009-02-11 13:14:06

+0

这些盐是使用彩虹桌的攻击者已知的。 – 2009-02-11 13:45:17

1

盐应该有尽可能多的熵以确保给定的输入值被多次散列,结果散列值将尽可能接近,总是不同的。

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

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

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

3

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

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

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

+2

彩虹表的全部要点是这些值是预先生成的,并且如果您为表格生成一个值(例如密码),则加上一个给定的常量,这是一个完全不同的表格,您也可以直接尝试哈希结果。 :) – 2009-02-11 13:42:48

+1

恒定的散列值不值。所有的密码都可以使用一个彩虹桌进行破解。盐的目的是制造彩虹桌是不可能的。 – 2009-02-11 13:46:42

7

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

虽然这并没有增加对字典式攻击等的安全性,但它确实消除了边缘情况,即有人将他们的salt和hash复制到另一条记录,以便用自己的密码替换密码。

(诚然这是很难想象一种情况,其中适用的,但我可以看到在腰带和背带没有坏处,当涉及到安全性。)

29

使用高熵盐是绝对必要的店密码安全。

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

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

They used to have a 12-bit salt。 12位是4096个不同的组合。这不够安全,因为that much information can be easily stored nowadays。这同样适用于4096个最常用的用户名。很可能您的一些用户会选择属于最常用用户名的用户名。

我找到了这个password checker,它计算出你的密码的熵。在密码中使用较小的熵(比如使用用户名)会使彩虹表变得更容易,因为它们试图至少覆盖所有低熵密码,因为它们更可能发生。

3

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

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

8

确实,由于用户可能在不同网站之间共享用户名,因此用户名可能会出现问题。但是,如果用户在每个网站上有不同的名字,这应该是没有问题的。那么为什么不在每个网站上使它独一无二。有些哈希密码,这样

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

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