我今天做了很多研究,并且已经学习了很多关于哈希和加密的知识(以及两者之间的重要区别)。我学到的一件事是:人们对腌制的功效持不同意见。
在对此question的回复中(特别是在对已接受答案的评论中),人们总结 - 似乎 - 在数据库中将散列密码旁边的随机生成的盐存储为< / em>保护密码的最佳方式。有几个资源说明了这一点,这将是我的问题的基础。
在这个question中,接受的答案表明,通过访问所有可能的散列数据值,盐并没有做太多 - 只是为了让事情变得更加安全(尽管如此)不可靠的大量存储数据)。盐和散列算法的目的是增加单个密码输入的可能性,使得对数据库的基于字典的攻击的使用效率呈指数级下降(这里,我使用术语&#34;基于字典的&#34更自由地,真实地 - 引用 - 表,无论是彩虹表,用于暴力攻击的表(每次重新计算),还是简单的查找表。
根据我的理解,加密良好的密码需要三(3)件事情:
为了让黑客能够理解产生的存储哈希值,他或她需要四(4)件事情:
分歧似乎围绕着如何处理盐,即在哪里储存盐。我一直看到的关于Stack Overflow的短语是&#34;默默无闻的安全&#34; - 这似乎是一个盐的前提(&#34;让这些信息更少,可见&#39;&#34;);但是,从我的阅读中,我逐渐明白,默默无闻的安全并不是真的有效。其前提似乎是:如果攻击者可以访问算法,并且 - 如果提供 - 盐,他或她可以弄清楚。
然后,安全性的前提不仅仅是混合和更改值,而是指数据库,事务或服务器使用停止攻击的类型: / p>
另一位用户评论说,如果代码暴露给攻击者并不重要,好的代码 - 或者一个好的安全算法 - 会阻止攻击成功。 因此,安全性是三(3)件事的组合: 对有效性盐的关注似乎源于攻击者本身可以访问数据库的假设。 场景:我有一本字典,你的盐和你的哈希算法。抓住你的密码应该没有真正的麻烦(这就是为什么我们努力阻止暴力攻击)。 所以,作为这些结论(现在在Stack Overflow斩波块上)的结果我的问题是: 盐的安全性似乎在于攻击者没有它,而不是严格的随机性 基本上,所有这些安全性都是&#39; (关于哈希的功效等)只是神话?也许我只是回应这样一个想法,即没有任何东西真的可以完全被黑客证明(我们只做我们能做的一切)? 在我看来,如果您的数据库被暴露,那么盐 - 随机或非随机 - 并不重要,特别是如果数据库存储了盐。 然后,最佳做法是双重的(盐只增加了一点安全性):( 1)敏感信息的散列; (2)在这个问题的背景下保护数据库免受暴力攻击。 似乎有很多错误信息在SO 周围浮动(其中一些可能存在于我上面得出的理解中)。 在这里,我假设防范跨站点脚本等已经到位。
问题
为什么我有动力去问
答案 0 :(得分:4)
安全性更多的是保护代码的位置而不是散列存储的信息吗?
安全性是关于构建攻击媒介的缓解措施。有许多类型的攻击和许多类型的缓解。你偶然发现了其中几个。
Salt(与哈希一起存储的随机字符串)可以防止特定的攻击媒介 - 由可以访问整个表的恶意用户发起的rainbow attack。
Pepper(存储在不同位置的加密随机,秘密盐值)可防止其他内容 - 恶意用户发起的dictionary或brute force攻击,可访问散列值和盐对于特定用户,但无法访问其他系统(尤其是存储辣椒的系统)。
如果你正在阅读这篇文章,你会发现许多专家都认为辣椒或多或少是无用的,并且通过默默无闻来构成安全。&#34;他们之所以这么认为是因为他们至少在原则上相信,如果一个破解者可以访问你的数据库,那么他几乎肯定可以访问持有胡椒的存储位置。
为什么为每个(在这种情况下)生成一个随机盐密码问题,特别是如果数据库已经暴露,即盐随机性是否真的增加了信息的安全性?
为了理解为什么这很重要,您必须了解rainbow table如何用于加速攻击。使用彩虹表,破解者可以计算常见密码的所有已知哈希值,并扫描整个数据库表以查找它们。这比对每个条目的暴力攻击要快得多。如果将盐与密码组合在一起,则会使彩虹表无效。最后,通过使问题在计算上不可行,可以减缓饼干的速度。
盐的安全性似乎在于攻击者没有它,而不是它的随机性
这绝对不正确。这一切都是关于将哈希的输入从可预测的东西(例如字典中的单词)改变为不可预测的东西(一个单词与随机字符串组合),这也是为了阻止彩虹表。
为什么要将盐存储在数据库中?
当用户登录时,他提供密码而不是盐(他甚至不知道盐)。然后必须将输入的值与盐组合,然后进行散列。系统将此哈希与存储在数据库中的哈希进行比较。如果存在完全匹配,则系统可以推断使用用户输入的相同密码创建散列值,从而验证身份验证尝试。
由于用户不知道盐,因此数据库必须存储它。
答案 1 :(得分:1)
密码密码是对抗彩虹表攻击的对策。
考虑具有以下条目的数据库
User | Password
Jim | x7291s
Jane | m09var
Jill | x7291s
Jack | 983d2w
并考虑下面的彩虹表,它存储了一个黑客可能用来尝试在db中找到密码哈希值的常用密码:
Hash | Password
x7291s | password1
983d2w | puppies
34980f | 12345
302jf0 | opensesame
黑客可以轻松找到常用密码,而无需自己计算或破解任何哈希值。 Jim Jack和Jill受到了损害,而使用更加模糊的密码的jane已经免于妥协。
没有盐,散列函数总是看起来像:
hash_me("password1") -> x7291s
然而用盐:
hash_me("password1 208ejd209kj4ed02" ) -> mt2d89 // using Jack's salt
hash_me("password1 3094kf04390f0s9k" ) -> 3409fk // using Jill's salt
hash_me("password1 saf890af9k3049kf" ) -> f7g6s7 // using Jim's salt
你可以看到彩虹表失去了它的功效,不再可用了。 mt2d89
3409fk
或f7g6s7
都不会与密码1的x7291s
匹配
答案 2 :(得分:0)
如果数据库受到损害,salt的目的是提供额外的保护。如果您认为数据库不能被泄露,您只需将所有内容存储在纯文本中,基于密码的身份验证系统就可以正常工作。问题是密码数据库一直受到危害。
John Wu和Michael Burr已经说明了为什么你想要一个盐来防止相同的密码出现在数据库中的相同哈希。
如果使用salt,则必须将其存储在数据库中。否则,如果不使用所有可能的盐散列给定密码,则无法对合法用户进行身份验证。因此,如果攻击者可以访问数据库条目,攻击者也可以访问盐。
如果攻击者可以访问数据库条目,我们希望最大限度地增加攻击者通过强力发现密码所需的工作量和时间。如果没有salt,攻击者可以预先计算(在访问数据库之前)并存储彩虹表,这基本上是通过散列函数运行的潜在密码列表。查找彩虹表中的数据库条目非常快,因此如果攻击者可以存储一个并且可以访问数据库,则会立即发现密码。当使用盐时,所需彩虹表的大小随盐长度呈指数增长,因此使用足够大的盐将有效地排除彩虹表的使用。
攻击者仍然可以强制数据库条目。使用已知的salt和hash算法,攻击者将检查字典。这很慢,因为攻击者无法预先计算任何东西;攻击者必须使用数据库中发现的salt。如果密码不在字典中,则攻击者必须使用猜测密码。最终,他们会发现密码。这也是密码过期有用的原因。如果强制哈希的预期时间大于密码有效期,则在攻击者暴力破解之前您将更改密码。