【问题标题】:Why do we use the "salt" to secure our passwords?为什么我们使用“盐”来保护我们的密码?
【发布时间】:2011-07-12 07:06:57
【问题描述】:

我正在阅读this tutorial,我遇到了以下关于加密的讨论。最后写着

在最后一行,我们用密码对盐进行了哈希处理,得到了一个 实际上是加密的密码 无法破解

但在我看来,同时拥有encrypted_passwordsalt 的黑客可以像使用salt 一样执行“彩虹”技巧。

那么,我哪里错了?

谢谢!

$ rails console
>> require 'digest'
>> def secure_hash(string)
>>   Digest::SHA2.hexdigest(string)
>> end
=> nil
>> password = "secret"
=> "secret"
>> encrypted_password = secure_hash(password)
=> "2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b"
>> submitted_password = "secret"
=> "secret"
>> encrypted_password == secure_hash(submitted_password)
=> true

这里我们定义了一个函数,叫做 使用加密的secure_hash 散列函数称为 SHA2,是 SHA 系列哈希函数,我们 通过摘要包含到 Ruby 中 library.7 知道并不重要 这些哈希函数究竟是如何工作的; 为了我们的目的,重要的是 他们是单向的:没有 计算上易于处理的方法 发现

2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b 是字符串的 SHA2 哈希 “秘密”。

但是,如果您考虑一下,我们 还有一个问题:如果攻击者 曾经掌握过散列密码, 他还有机会 发现原件。为了 例如,他可以猜到我们使用了 SHA2,所以写一个程序 将给定的哈希值与哈希值进行比较 潜在密码的值:

>> hash = "2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b"
>> secure_hash("secede") == hash
=> false
>> secure_hash("second") == hash
=> false
>> secure_hash("secret") == hash
=> true

所以我们的攻击者有一个匹配 - 坏消息 对于任何具有密码“秘密”的用户。 这种技术被称为彩虹 攻击。

为了阻止潜在的彩虹攻击,我们 可以使用盐,这是一种不同的 每个用户的唯一字符串。8 一个 (几乎)确保的常用方法 唯一性是散列当前时间 (在 UTC 中与时区无关) 连同密码,这样两个 只有在以下情况下,用户才会有相同的盐 它们的创建方式完全相同 时间和密码相同。让我们 看看这是如何使用的 中定义的secure_hash函数 上面的控制台:

>> Time.now.utc
=> Fri Jan 29 18:11:27 UTC 2010
>> password = "secret"
=> "secret"
>> salt = secure_hash("#{Time.now.utc}--#{password}")
=> "d1a3eb8c9aab32ec19cfda810d2ab351873b5dca4e16e7f57b3c1932113314c8"
>> encrypted_password = secure_hash("#{salt}--#{password}")
=> "69a98a49b7fd103058639be84fb88c19c998c8ad3639cfc5deb458018561c847"

在最后一行,我们用密码对盐进行了哈希处理,得到了一个 实际上是加密的密码 不可能破解。 (为清楚起见, 散列函数的参数是 通常用--分隔。)

【问题讨论】:

标签: encryption


【解决方案1】:

彩虹表的计算成本很高。没有盐,您可以构建一个可以重复使用的彩虹表,因为密码“密码”将始终产生相同的哈希(md5=5f4dcc3b5aa765d61d8327deb882cf99,sha1=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8),因此很容易在密码数据库中识别。

对于盐,您必须为遇到的每种盐计算一个彩虹表。一个大小合适的盐,比如 32 位(理想情况下,128 位甚至更多),意味着您必须为要破解的每个密码计算一个彩虹表,从而大大违背了它的目的。

【讨论】:

  • 但是你以后如何比较密码而不保存随机盐呢?如果盐是随机的,如果不跟踪它就无法知道它是什么,比如将它保存在数据库中。所以如果有人有数据库,他们也有盐!如果有人可以访问您的数据库,他们可能也可以访问您的代码,因此他们可以查看您还使用什么盐!
  • @Chloe:您将盐与密码一起保存。我通常将其分解并将部分插入到预定(未发布)位置的哈希中,只是为了给黑客带来一点额外的混乱来应对。但是即使黑客设法隔离了盐,由于我的回答中所述的原因,他们通常仍然不能使用彩虹表。
  • @Chloe:另一方面,您关于拥有代码的观点是不正确的。最常见的数据窃取方式是 SQL 注入攻击,它允许窃贼窃取数据库中包含的几乎所有内容,但通常不提供对业务层代码的访问。我并不是说代码不能被盗——它可以——但要困难得多,而且人们不必假定被盗数据意味着被盗代码。
  • @Chloe:当然,从黑客的角度来看,弱密码会提前失效,减少他们前面的工作,但这并不意味着强密码指日可待。每个密码的唯一盐意味着每个密码都从头开始,而强密码占据了难以处理的大空间(根据定义)。如果没有盐,建立在数百万 CPU 小时上的彩虹表会为他们的拉网带来更多数量级的密码。
  • @Chloe:顺便说一句,我同意彩虹表不像以前那么重要,但那是因为开发人员已经学会了给他们的密码加盐。如果每个人都停止加盐密码,你可以打赌彩虹桌会突然变得非常流行。
【解决方案2】:

Salt 是为了阻止某人预先计算“反向”查找表,使攻击者可以快速找到导致目标哈希的密码。创建其中一个表在计算上的工作量与暴力破解目标密码空间一样多,因此只有在可以在多个目标上使用该表时才值得。

盐可以防止这种情况;攻击者在生成表时需要考虑盐,因此该表仅适用于单个目标,攻击者又恢复了蛮力。

【讨论】:

  • 我想说的两倍以上(对于添加的每一位),如果黑客认真对待黑客攻击,您通常可以将板条定位在字符串的开头、结尾或中间,他将不得不补偿至少在开始和结束时都有板条,因此可能需要三倍的存储空间。
  • +1,第一段第二句是重点观察。
  • @erickson:是的,但由于盐是公开的,他可以创建一个新的彩虹表,不是吗? (攻击者)
  • @gio 他为什么要这么做?
  • @erickson:我的意思是攻击者。据称,盐用于使攻击者更难预先计算某些表。但是一旦他知道了盐,他就可以再次预先计算表格
【解决方案3】:

是的,你是对的,如果有人知道你的算法和盐,他可以生成一个彩虹表。但是,生成彩虹表需要很长时间,因为允许的字符越多。

例如,如果您有一个由 10 个字符组成的密码,这些字符都是数字,那么您就有 10^10 种可能性。如果您允许使用大小写字母字符,则最多有 62^10 个可能性,只有 8.39 * 10^17 个排列;这仅适用于 10 个字符的密码,您还必须考虑低于或高于该长度的任何长度,具体取决于您允许的密码长度。

生成这样的表需要很长时间,而算法本身的彩虹表可能很容易获得,salt 会修改算法以使其成为您自己的,并且为此存在表的可能性非常低。

【讨论】:

  • 很好的解释。据我了解,它基本上只是使密码变长以降低猜测它的可能性。
  • 并非如此。它不会更改密码,在理想情况下,它会花费完全相同的时间来强制它,无论是否加盐。如果攻击者拥有数据库,salt 是一种防御机制。如果您使用已知的算法,很可能有一个明文数据库:哈希映射现成可用。如果您在散列之前操作明文,这些表将变得无用,您需要为每个盐生成一个表。如果您的数据库中的每个密码都有一个 salt,那么您需要为每个密码生成一个表。
【解决方案4】:

如果您使用 salt(即使它是公开的但对站点而言是唯一的),您将获得免受哈希字典的保护,其中经常使用的密码已经过哈希处理。

如果您的盐是安全的,那么他们就无法使用超级计算机对其进行暴力破解。他们必须使用您的服务器检查所有可能的密码(希望有某种形式的暴力保护)。

【讨论】:

  • 如果他们有哈希值和盐,他们可以尝试在他们自己的系统上暴力破解它,所以你的服务器上的暴力破解对这类攻击没有任何作用(当他们已经获取您的登录信息)。我们可以放心地假设他们可以得到算法。
  • @vbence:您不会在站点上使用单一盐。您为每个密码使用不同的盐。
  • 是的,这正是我写的,公共盐只保护字典,秘密盐防止他们在自己的系统上进行破解。 - 我不是在谈论黑客场景,他们可能会将您的加盐算法与您的数据结合在一起。
  • @Marcelo Cantos 我在帖子中避开了这个话题,因为它可能是我很乐意参与的更长对话的主题。
  • @vbence:固定盐比每个密码的盐弱。我不知道有多少关于这个话题的讨论。
猜你喜欢
  • 1970-01-01
  • 2015-12-17
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
相关资源
最近更新 更多