为什么我们使用“盐”来保护我们的密码?

时间:2011-03-09 22:19:17

标签: encryption

我正在阅读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
     

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

     

为了阻止潜在的彩虹攻击,我们   可以使用盐,这是一个不同的   每个用户的唯一字符串.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"
     

在最后一行,我们用密码对盐进行了哈希处理,产生了一个   虚拟加密密码   不可能破解。 (为清楚起见,   散列函数的参数是   经常用 - 。分开。)

4 个答案:

答案 0 :(得分:32)

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

使用盐,您必须为遇到的每种盐计算彩虹表。一个大小合适的盐,比如32位(理想情况下,128甚至更多),意味着您必须为每个要破解的密码计算彩虹表,从而在很大程度上破坏其目的。

答案 1 :(得分:7)

Salt旨在阻止某人预先计算“反向”查找表,该表允许攻击者快速找到导致目标哈希的密码。创建这些表中的一个是计算上的工作,与强制目标密码空间一样多,所以只有在许多目标上使用该表才有意义。

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

答案 2 :(得分:2)

如果您使用salt(即使它是公共的,但只是一个站点),您将获得哈希字典的保护,其中经常使用的密码已经过哈希。

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

答案 3 :(得分:2)

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

因此,例如,如果您的密码由10个字符组成,这些字符都是数字,则您有10 ^ 10个可能性。如果你允许使用大写和小写字母字符,那么这可能会达到62 ^ 10个可能性,仅为8.39 * 10 ^ 17个排列;并且这仅适用于10个字符的密码,您还必须考虑低于该字符和以上的任何长度,具体取决于您允许的密码长度。

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