Encryption 我们为什么要使用;盐“;保护我们的密码?

Encryption 我们为什么要使用;盐“;保护我们的密码?,encryption,Encryption,我正在阅读,遇到了以下关于加密的讨论。最后写着 在最后一行中,我们用密码对salt进行了哈希运算,得到了一个 加密密码,实际上是 无法破解 但在我看来,一个同时拥有加密密码和salt的黑客可以像我们使用salt一样玩“彩虹”把戏 那么,我错在哪里 谢谢 这里我们定义了一个函数,名为 使用加密 名为SHA2的散列函数,是 SHA系列散列函数,我们 通过摘要包含到Ruby中 图书馆知道并不重要 这些散列函数是如何工作的; 就我们的目的而言,重要的是 他们是单向的:没有 计算简便的方法 发现 2BB8

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

在最后一行中,我们用密码对salt进行了哈希运算,得到了一个 加密密码,实际上是 无法破解

但在我看来,一个同时拥有
加密密码
salt
的黑客可以像我们使用
salt
一样玩“彩虹”把戏

那么,我错在哪里

谢谢

这里我们定义了一个函数,名为 使用加密 名为SHA2的散列函数,是 SHA系列散列函数,我们 通过摘要包含到Ruby中 图书馆知道并不重要 这些散列函数是如何工作的; 就我们的目的而言,重要的是 他们是单向的:没有 计算简便的方法 发现

2BB80D537B1DA3B38BD30361AA855686BDE0EACD7162FEF6A25FE97BF527A25B 是字符串的SHA2散列 “秘密”

不过,如果你仔细想想,我们 还有一个问题:如果攻击者 曾经掌握过散列密码, 他仍然有机会获得成功 发现原作。对于 例如,他可以猜到我们使用了 SHA2,然后编写一个程序 将给定哈希值与哈希值进行比较 潜在密码的值:

>> hash = "2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b"
>> secure_hash("secede") == hash
=> false
>> secure_hash("second") == hash
=> false
>> secure_hash("secret") == hash
=> true
所以我们的攻击者有一个坏消息 对于密码为“secret”的任何用户。 这种技术被称为彩虹 攻击

为了挫败潜在的彩虹攻击,我们 可以用盐,这是一种不同的方法 每个用户的唯一字符串。8一个 确保(几乎)安全的常用方法 唯一性是散列当前时间 (以UTC为时区-独立) 随着密码,使两个 只有在以下情况下,用户才会有相同的盐 它们是在完全相同的位置创建的 时间和密码相同。让我们 使用 中定义的secure_散列函数 上面的控制台:

>> 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"
在最后一行中,我们用密码对salt进行了哈希运算,得到了一个 加密密码,实际上是 无法破解。(为清楚起见, 散列函数的参数是 经常用--)隔开


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

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

如果你使用salt(即使它是公共的,但对一个站点来说是唯一的),你将得到哈希字典的保护,因为经常使用的密码已经被哈希了


如果你的盐是安全的,那么他们就不能用超级计算机来强制它。他们必须与您的服务器检查每一个可能的密码(我们希望它有某种形式的暴力保护)。

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


盐可以防止这种情况;攻击者在生成表时需要对salt进行说明,因此该表仅适用于单个目标,而攻击者又回到了暴力状态。

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

例如,如果你有一个由10个字符组成的密码,这些字符都是数字,那么你有10^10个可能性。如果您允许按字母顺序排列的小写和大写字符,这将增加到62^10个可能性,仅为8.39*10^17个排列;这仅适用于10个字符的密码,您还必须考虑低于该长度和高于该长度的任何长度,这取决于您允许的密码长度


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

许多其他问题的重复。如果有哈希值和salt,则可能重复,他们可以尝试在自己的系统上对其进行暴力攻击,因此服务器上的暴力保护对于此类攻击(当他们获得您的登录信息时)将毫无作用。我们可以放心地假设他们可以得到算法。@vbence:你不能在一个站点上使用一种盐。每个密码使用不同的密码。是的,这正是我写的,公共密码只保护字典,秘密密码保护他们不破坏自己的系统。-我不是说黑客可能会将你的salt算法与你的数据结合起来。@Marcelo Cantos我在帖子中避免了这个话题,因为它可能是我很乐意参与的较长对话的主题。@vbence:固定salt比每个密码的salt弱。我不知道有多少关于这个话题的讨论。我想说的不止一倍(对于每增加一个位),如果黑客对黑客是认真的,你可以将板条放在字符串的开头、结尾或中间,他必须在开头和结尾至少补偿slat,因此可能需要三倍的存储空间。+1,第一段的第二句是关键观察。@erickson:是的,但从那时起
>> 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"