隐藏盐以进行哈希处理的必要性


99

在工作中,我们有两种相互竞争的盐理论。我从事的产品使用诸如用户名或电话号码之类的东西来加杂凑。从本质上讲,每个用户都有所不同,但我们可以随时使用。其他产品会为每个用户随机生成一个盐,并在用户每次更改密码时都会更改它。然后将盐在数据库中加密。

我的问题是第二种方法是否真的必要?从纯粹的理论角度我可以理解,它比第一种方法更安全,但是从实用性角度来看又如何呢?现在要对用户进行身份验证,必须对salt进行加密,并将其应用于登录信息。

在考虑之后,我只是看不到这种方法真正的安全性收益。即使在攻击者知道如何快速确定每个帐户的含义的情况下,一个帐户一个帐户地更改盐,仍然使某人尝试强行使用哈希算法仍然非常困难。假设密码足够强。(显然,找到一组均为两位数字的密码,正确的哈希值要比找到正确的8位密码的哈希值容易得多)。我的逻辑是否正确,或者我缺少什么?

编辑:好的,这就是为什么我认为加密盐真的没有意义。(让我知道自己是否走对了路)。

对于以下说明,我们假设密码始终为8个字符,salt为5,并且所有密码均由小写字母组成(这使数学更容易了)。

每个条目具有不同的盐值意味着我不能使用相同的彩虹表(实际上,如果我有一个足够大的表,我可以使用,但是暂时暂时忽略它)。从我的理解中,这是盐的真正关键,因为要破解每个帐户,我都必须重新发明轮子,以便为每个帐户说话。现在,如果我知道如何对密码应用正确的盐来生成哈希,我会这样做,因为盐实际上只是在扩展哈希短语的长度/复杂度。因此,我将减少生成“知道”密码(从13 ^ 26到8 ^ 26的密码)所需的可能组合的数量,因为我知道盐是什么。现在,它变得更容易,但仍然非常困难。

因此就加密了盐。如果我知道盐是加密的,那么我不会尝试对其进行解密(假设我知道它具有足够的加密级别)。我会忽略它。回到上一个示例,而不是试图弄清楚如何解密它,我只会生成一个更大的Rainbow表,其中包含13 ^ 26的所有密钥。不知道加盐肯定会使我慢下来,但是我认为这不会增加尝试先破解加盐加密的艰巨任务。这就是为什么我认为这不值得。有什么想法吗?

以下是描述在暴力攻击下密码将保留多长时间的链接:http : //www.lockdown.co.uk/? pg=combi


好问题,凯文,很及时。我无法评论安全性,但是可以肯定的是,所有这些加密和解密都会对性能造成影响。
DOK

您无需忽略大小合适的Rainbow表-该表也使加密的食盐无意义,因为它可以解密咸的哈希并再次用于解密原始哈希。好消息是,创建表格可能需要几个世纪的时间。
08年

让我感到兴奋的是,我不确定要创建这么大的彩虹表会花费这么长时间。他是个古怪的主意,采用像Kraken这样的分布式计算平台(确实是这样)来生成它。那要花多长时间?
kemiller2002

3
@Kevin:SHA1返回一个40个字符的十六进制字符串,因此有40 ^ 16个可能的返回值。假设一台计算机每秒可以计算1000个哈希,我计算出100万台计算机将花费大约100亿年的时间来生成能够确定该大小字符串的彩虹表。
08年

+1好问题,您也读得很好。我认为您对这个问题的回答有误。的始终应该是一个秘密,因为在获得哈希之前,哈希不能被破坏。你应该阅读有关CWE-760(cwe.mitre.org/data/definitions/760.html

Answers:


45

答案是问自己,您到底想保护什么?如果某人可以访问您的数据库,那么他们就可以访问加密的盐,也可能也可以访问您的代码。他们可以用所有这些解密加密的盐吗?如果是这样,那么无论如何加密几乎是无用的。确实存在盐,因此如果被破坏,就不可能形成彩虹表来一次性破解整个密码数据库。从这种角度来看,只要每种盐都是唯一的,就没有区别,则您的盐或每个密码分别使用加密的盐就需要进行蛮力攻击。


Kinda对这些概念感到陌生。因此,它看起来像是一个幼稚的问题,但是在知道每个密码的盐值的情况下形成彩虹表会不会更容易,因为您将尝试为每个可能的密码仅对盐值进行一次组合?
stdout

来自1000个常用密码的ranbow表将以与散列几乎相同的速度破解该密码。唯一可行的方法是,如果您假设密码的分配是统一的..我们知道它们不是
DaWNFoRCe

100

隐藏盐是不必要的。

每个哈希都应使用不同的盐。实际上,通过从加密质量随机数生成器中获取8个或更多字节可以轻松实现这一点。

根据我的先前回答

Salt有助于阻止预先计算的字典攻击。

假设攻击者拥有一个可能的密码列表。他可以对每个哈希进行哈希处理,然后将其与受害者密码的哈希进行比较,看是否匹配。如果列表很大,这可能需要很长时间。他不想在下一个目标上花费太多时间,因此他将结果记录在“字典”中,其中哈希值指向其对应的输入。如果密码列表非常长,他可以使用诸如Rainbow Table之类的技术来节省空间。

但是,假设他的下一个目标使他们的密码变了。即使攻击者知道盐是什么,他的预先计算的表也毫无价值-盐会更改每个密码产生的哈希。他必须重新散列列表中的所有密码,并将目标的盐附加到输入中。每个不同的盐都需要使用不同的字典,如果使用了足够的盐,则攻击者将没有足够的空间来存储所有字典。节省时间的交易空间不再是一种选择;攻击者必须退回去哈希列表中要攻击的每个目标的每个密码。

因此,不必保守盐的秘密。确保攻击者没有与该特定盐对应的预先计算的字典就足够了。


再多考虑一下之后,我意识到让自己认为盐可以隐藏是很危险的。最好假设盐不能被隐藏,尽管如此,还是要设计安全的系统。我在另一个答案中提供了更详细的解释


但是,NIST最近的建议鼓励使用附加的秘密“盐”(我见过其他人将此附加秘密称为“胡椒粉”)。可以使用此秘密作为盐来执行密钥派生的其他迭代。此回合不会增加对预先计算的查找攻击的抵抗力,而是防止密码猜测,就像在良好的密钥派生函数中进行大量迭代一样。如果与哈希密码一起存储,此秘密将毫无用处。必须将其作为秘密进行管理,而在大型用户数据库中可能很难做到这一点。


1
隐藏盐是必要的,因为在获得哈希之前,哈希不能被破坏。这与CWE-760(cwe.mitre.org/data/definitions/760.html)有关
菜鸟

28
@The Rook-不,您误解了这个问题。它指使用可预测的盐。它没有说任何关于保持盐的秘密。确实,如果不使用其他秘密就无法真正保留盐的秘密……在这种情况下,为什么不使用第二个秘密作为盐呢?将用户名用作盐是不好的,因为多个系统可能共享同一用户名,这使得为该特定盐建立表更值得。随机盐是最好的,但不必保密。
艾里克森(Erickson),2010年


1
@erickson,我想您在这里混用术语。除非隐藏,否则盐不会阻止字典攻击。大量盐分公开存放。而且,如果您知道盐的用法,那么将盐添加到词典术语中的时间只会减慢字典攻击的速度:)盐可防止Rainbow表查找....速度非常快。如果攻击者知道您的想法,则不会受到字典攻击的保护。如果攻击者不了解您的想法,那么您可以免受字典攻击,他们必须使用蛮力攻击。
Ultratrunks

4
@Ultratrunks是的,我已使用术语“预先计算的字典攻击”澄清了有关此主题的一些答案。它比Rainbow表更通用,它指的是允许使用散列作为键对明文进行反向查找的任何结构。无论您选择什么术语,我都会明确解释盐是用来击败Rainbow表和类似机制的。您应该始终假设攻击者知道盐。如果有可能将其保密,则无需对密码进行哈希处理。
埃里克森

3

我对“盐”的理解是,它使破解更加困难,但它并没有试图隐藏额外的数据。如果您试图通过使盐成为“秘密”来获得更高的安全性,那么您实际上只是希望加密密钥中有更多位。


3

第二种方法只是稍微安全些。盐可以保护用户免受字典攻击和彩虹表攻击。它们使雄心勃勃的攻击者更难以破坏您的整个系统,但仍然容易受到针对系统中一个用户的攻击。如果您使用诸如电话号码之类的公开信息,并且攻击者意识到了这一点,那么您已经为他们节省了攻击的一步。当然,如果攻击者获得了您的整个数据库,盐和所有内容,那么这个问题就没有意义了。

编辑:在重新阅读了这个答案和一些评论之后,我觉得有些困惑可能是由于我只比较问题中出现的两个非常具体的情况:随机盐与非随机盐。的问题,使用电话号码作为盐是没有实际意义,如果攻击者得到你的整个数据库,不是在所有使用盐的问题。


他们如何防止字典攻击?
08年

通过强迫攻击者为每个密码和盐的组合创建新的字典。不用盐,一本字典可用于整个密码表。
比尔蜥蜴

“如果攻击者获得了您的整个数据库,盐和所有资源,那么问题当然就没有了。” 这不是为什么盐被加密吗?
Patrick McElhaney,

1
@比尔:您刚刚描述了一张彩虹桌。字典攻击是我接受普通单词并尝试对其进行身份验证的地方。这是一种蛮力,答案空间大大减少了。没有哈希可以抵御蛮力。
偷渡

我从未听说过这种做法,但我不是安全专家。似乎对独特的盐进行加密将为彩虹表攻击增加一层额外的保护。
比尔蜥蜴

3

...类似用户名或电话号码的哈希值。...

我的问题是第二种方法是否真的必要?从纯粹的理论角度我可以理解,它比第一种方法更安全,但是从实用性角度来看呢?

从实际的角度来看,盐是实现的细节。如果要更改用户信息的收集或维护方式(有时还会更改用户名和电话号码,以使用确切的示例),则可能已损害了安全性。您是否希望这种面向外部的更改具有更深层次的安全问题?

是否要停止要求每个帐户都具有电话号码的要求就需要进行完整的安全检查,以确保您没有针对安全漏洞而开放这些帐户?


2
更不用说您是否在使用一些任意的用户信息,当他们更改该信息时,您需要他们再次输入密码,以便您可以使用新的密码再次对其进行加密。
Treborbob 2012年

3

隐藏的盐不再是盐。是胡椒 它有它的用途。它不同于盐。

Pepper是添加到密码+盐中的秘密密钥,使哈希成为HMAC(基于哈希的消息身份验证代码)。从理论上讲,有权访问哈希输出和盐的黑客可以通过蛮力猜测将生成哈希的输入(并因此通过密码文本框中的验证)。通过添加Pepper,您可以以密码随机的方式增加问题空间,使问题变得棘手,而无需使用严重的硬件。

有关胡椒的更多信息,请点击此处

另请参见hmac


2

这是一个简单的示例,显示为什么对每个散列使用相同的盐是不好的

考虑下表

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

情况1,当salt 1与salt2相同时 如果将Hash2替换为Hash1,则用户2可以使用用户1密码登录

情况2,当盐1与盐2不同时 如果将Hash2替换为Hash1,则user2无法使用用户1密码登录。


我们没有为每个帐户使用相同的哈希,而是为每个哈希使用相同类型的信息。例如,一个帐户,所述盐是该帐户的PHONENUMBER等
kemiller2002

我知道这已经过去了很长时间,但是...您不能依靠盐来防御此类攻击。我们必须假设,除了密码(即密码)外,攻击者还不了解认证系统的所有信息。因此,我们必须假设攻击者知道a)我们用作盐类的东西(大多数情况下以明文形式存储在同一数据库和表中)和b)我们如何用盐类进行哈希处理(即,追加,哈希两次,等等)。如果用户有能力切换哈希,那么我们必须假设他们也可以切换盐。盐在这里无济于事。
Dave Satch 2014年

1

有两种技术,具有不同的目标:

  • “盐”用于使两个否则相等的密码进行不同的加密。这样,入侵者就无法有效地对整个加密密码列表使用字典攻击。

  • 在对消息进行哈希处理之前,添加了(共享的)“秘密”,以使入侵者无法创建自己的消息并使它们被接受。


0

我倾向于隐藏盐。我使用10位数的盐,将1到1024之间的随机数放在密码的开头,然后再对它进行哈希处理。将用户输入的密码与哈希进行比较时,我从1循环到1024,并尝试所有可能的salt值,直到找到匹配项。这花费不到1/10秒。我从PHP password_hashpassword_verify有了这样的想法。在我的示例中,“成本”是10盐分的10。或从另一个用户说的话来看,隐藏的“盐”称为“胡椒粉”。该盐未在数据库中加密。它被强行淘汰了。这将使彩虹表有必要将散列逆转大1000倍。我使用sha256是因为它速度很快,但仍然被认为是安全的。


因此,如果我的密码是“ 345678”,而您所撒的随机盐恰好是“ 12”。如果有人输入“ 45678”作为我的密码。在许多方面这似乎是错误的。
Yurippenet

-1

确实,这取决于您要保护数据的攻击类型。

对每个密码使用唯一的盐的目的是为了防止针对整个密码数据库的字典攻击。

对每个密码加密唯一的符号会使破解单个密码更加困难,是的,但是您必须权衡是否真的有很多好处。如果攻击者通过蛮力发现以下字符串:

Marianne2ae85fb5d

散列到存储在数据库中的哈希值,难道真的很难弄清楚密码是哪一部分,盐是哪一部分?


2
如果有人用强力手段无法猜出密码,我想说的是无论如何,因为显然他们拥有的技术还没有人想到。
实例猎人
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.