更新:我最近从这个问题中了解到,在下面的整个讨论中,我(我确信其他人也这样做)有点令人困惑:我一直称之为彩虹表,实际上称为哈希表.彩虹桌是更复杂的生物,实际上是Hellman Hash Chains的变种.虽然我认为答案仍然是相同的(因为它不归结为密码分析),但有些讨论可能有点偏差.
问题是:" 什么是彩虹表,它们是如何使用的? "
通常,我总是建议使用加密强随机值作为salt,与哈希函数(例如密码)一起使用,例如防止彩虹表攻击.
但实际上盐是随机的加密必需吗?在这方面,任何唯一值(每个用户唯一,例如userId)是否足够?实际上,它会阻止使用单个Rainbow Table来破解系统中的所有(或大多数)密码......
但是缺少熵真的会削弱散列函数的加密强度吗?
注意,我不是在问为什么要使用salt,如何保护它(它不需要),使用单个常量哈希(不要),或者使用什么样的哈希函数.
无论盐是否需要熵.
感谢所有答案到目前为止,但我想集中讨论我(有点)不太熟悉的领域.主要是对密码分析的影响 - 如果有人从密码数学PoV获得一些输入,我会非常感激.
此外,如果还有其他未被考虑的向量,那也是很好的输入(参见@Dave Sherohman指向多个系统).
除此之外,如果您有任何理论,想法或最佳实践 - 请使用证据,攻击情景或经验证据来支持这一点.或者甚至是可接受的权衡的有效考虑因素......我对该主题的最佳实践(资本B资本P)很熟悉,我想证明这实际上提供了什么价值.
编辑:这里有一些非常好的答案,但我认为正如@Dave所说,它归结为Rainbow Tables的常见用户名......以及可能不太常见的名称.但是,如果我的用户名是全局唯一的呢?不一定是我的系统唯一,但每个用户 - 例如电子邮件地址.
没有动力为单个用户构建RT(正如@Dave强调的那样,盐不会保密),这仍然会阻止群集.唯一的问题是我可能在不同的网站上有相同的电子邮件和密码 - 但盐无论如何都不会阻止它.
因此,它回归到密码分析 - 是否需要熵?(我目前的想法是从密码分析的角度来看没有必要,但这是出于其他实际原因.)
传统上,Salt存储为哈希密码的前缀.这已经使任何具有访问密码哈希的攻击者知道.使用用户名作为salt或不会影响该知识,因此,它不会影响单系统安全性.
但是,使用用户名或任何其他用户控制的值作为salt会降低跨系统安全性,因为在使用相同密码哈希算法的多个系统上具有相同用户名和密码的用户最终将使用相同的密码哈希每个系统.我不认为这是一个重大的责任,因为我作为攻击者,在尝试任何其他危害帐户的方法之前,会首先尝试使用目标帐户已在其他系统上使用过的密码.相同的哈希只能事先告诉我已知的密码可以工作,它们不会使实际的攻击变得更容易.(请注意,快速比较帐户数据库会提供更高优先级的目标列表,因为它会告诉我谁是谁以及谁不重用密码.)
这个想法的更大危险是用户名通常被重复使用 - 例如,您关注的任何网站都会有一个名为"Dave"的用户帐户,而"admin"或"root"更常见 - 这会使构建彩虹表,以更容易和更有效的方式定位具有这些常用名称的用户.
这两个缺陷都可以通过在对密码进行哈希处理之前在密码中添加第二个盐值(固定和隐藏或像标准盐一样暴露)来有效解决,但是,在这一点上,您可能无论如何只是使用标准的熵盐代替将用户名加入其中.
编辑补充: 很多人都在谈论熵和盐中的熵是否重要.它是,但不是因为大多数评论似乎都在思考.
一般的想法似乎是熵很重要,因此攻击者难以猜测盐.这是不正确的,事实上,完全无关紧要.正如各种人多次指出的那样,受盐影响的攻击只能由拥有密码数据库的人进行,而拥有密码数据库的人只能查看每个帐户的盐是什么.当你可以轻易查找时,它是否可猜测无关紧要.
熵重要的原因是避免盐值的聚类.如果salt基于用户名,并且您知道大多数系统都有一个名为"root"或"admin"的帐户,那么您可以为这两种盐制作彩虹表,它将破解大多数系统.另一方面,如果使用随机的16位盐并且随机值具有大致均匀的分布,则需要所有2 ^ 16种可能的盐的彩虹表.
这不是为了防止攻击者知道个人帐户的盐是什么,而是为了不给他们一个大盐脂的大目标,这个目标将用于大部分潜在目标.
使用高熵盐对于安全地存储密码是绝对必要的.
拿我的用户名'gs'并将其添加到我的密码'MyPassword'给gsMyPassword.这很容易使用rainbow-table打破,因为如果用户名没有足够的熵,那么这个值可能已存储在rainbow-table中,特别是如果用户名很短.
另一个问题是您知道用户参与两个或更多服务的攻击.有许多常见的用户名,可能最重要的用户名是admin和root.如果有人创建了一个与最常见用户名有盐的彩虹表,他可以使用它们来破坏帐户.
他们曾经有过12位盐.12位是4096种不同的组合.这不够安全,因为现在很容易存储大量信息.这同样适用于4096个最常用的用户名.您的一些用户可能会选择属于最常见用户名的用户名.
我找到了这个密码检查器,它可以解析你密码的熵.密码中的较小熵(例如使用用户名)使得彩虹表更容易,因为它们试图至少覆盖所有低熵密码,因为它们更有可能发生.
确实,单独的用户名可能是有问题的,因为人们可能在不同的网站之间共享用户名.但如果用户在每个网站上有不同的名称,那应该是没有问题的.那么为什么不在每个网站上使其独一无二.像这样散列密码
散列函数( "www.yourpage.com /" +用户名+ "/" +密码)
这应该可以解决问题.我不是密码分析的大师,但我确信我们不使用高熵的事实会使散列变得更弱.
我喜欢使用两者:高熵随机每记录盐,加上记录本身的唯一ID.
虽然这并没有增加对字典攻击等的安全性,但它确实消除了有人将其盐和哈希复制到另一条记录的意外情况,目的是用自己的密码替换密码.
(无可否认,很难想到这种情况适用的情况,但在安全方面,我认为腰带和牙套没有任何伤害.)