为什么我们使用“盐”确保我们的密码? [英] Why do we use the "salt" to secure our passwords?

查看:105
本文介绍了为什么我们使用“盐”确保我们的密码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


在最后一行,我们已经用密码加了盐,产生一个
加密的密码,实际上是
不可能破解


但在我看来,一个黑客谁拥有 encrypted_pa​​ssword salt 可以完全像我们使用



所以,我错了什么?



谢谢! / p>


  $ rails console 
>>需要'digest'
>> def secure_hash(string)
>> Digest :: SHA2.hexdigest(string)
>> end
=> nil
>> password =secret
=> secret
>> encrypted_pa​​ssword = secure_hash(password)
=> 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b
>> submitted_pa​​ssword =secret
=> secret
>> encrypted_pa​​ssword == secure_hash(submitted_pa​​ssword)
=> true

这里我们定义了一个名为
secure_hash的函数,它使用加密
哈希函数称为SHA2,部分
SHA系列的哈希函数,我们
通过摘要包含到Ruby中
library.7知道
的这些不是很重要散列函数工作;
为我们的目的重要的是
,他们是单向的:没有
计算易处理的方式
发现



2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b
是字符串
secret的SHA2哈希。



如果你想到它,我们
仍然有一个问题:如果攻击者
拥有哈希密码,
,他仍然有机会发现原始的
。对于
示例,他可以猜测我们使用
SHA2,因此写一个程序到
将给定的哈希值与潜在密码的
值进行比较:

 >> hash =2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b
>> secure_hash(secede)== hash
=> false
>> secure_hash(second)== hash
=> false
>> secure_hash(secret)== hash
=>真的

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



为了消除潜在的彩虹攻击,我们
可以使用盐,是每个用户不同的
唯一字符串。一个
通常的方式(几乎)确保
的唯一性是将当前时间hash
(以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_pa​​ssword = secure_hash(#{salt} - #{password})
=> 69a98a49b7fd103058639be84fb88c19c998c8ad3639cfc5deb458018561c847

在最后一行,我们已经使用了密码,产生
加密密码,实际上
不可能破解
。 (为了清楚起见,散列函数的
参数是
通常用 - 分隔)。



解决方案彩色表的计算价格昂贵。没有盐,你可以建立一个可以重复使用的彩虹表,因为密码密码将始终产生相同的哈希(md5 = 5f4dcc3b5aa765d61d8327deb882cf99,sha1 = 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8),因此在密码数据库中很容易识别。 / p>

使用盐,您必须为每个遇到的盐计算彩虹表。一个大小合适的盐,比如32位(理想的是128或甚至更多),这意味着你必须为每一个你想要破解的密码计算一个彩虹表,从而大大地打败了它的目的。


i was reading this tutorial, and i encountered the following discussion about encryption. At the end there's written

In the last line, we’ve hashed the salt with the password, yielding an encrypted password that is virtually impossible to crack

But in my opinion an hacker who has both the encrypted_password and the salt could do the "rainbow" trick exactly as if we were using the salt.

So, where i'm wrong?

Thanks!

$ 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

Here we’ve defined a function called secure_hash that uses a cryptographic hash function called SHA2, part of the SHA family of hash functions, which we include into Ruby through the digest library.7 It’s not important to know exactly how these hash functions work; for our purposes what’s important is that they are one-way: there is no computationally tractable way to discover that

2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b is the SHA2 hash of the string "secret".

If you think about it, though, we still have a problem: if an attacker ever got hold of the hashed passwords, he would still have a chance at discovering the originals. For example, he could guess that we used SHA2, and so write a program to compare a given hash to the hashed values of potential passwords:

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

So our attacker has a match—bad news for any users with password "secret". This technique is known as a rainbow attack.

To foil a potential rainbow attack, we can use a salt, which is a different unique string for each user.8 One common way to (nearly) ensure uniqueness is to hash the current time (in UTC to be time zone–independent) along with the password, so that two users will have the same salt only if they are created at exactly the same time and have the same password. Let’s see how this works using the secure_hash function defined in the console above:

>> 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"

In the last line, we’ve hashed the salt with the password, yielding an encrypted password that is virtually impossible to crack. (For clarity, arguments to hashing functions are often separated with --.)

解决方案

Rainbow tables are expensive to compute. Without the salt, you can build a rainbow table once that can be used repeatedly, since the password "password" will always yield the same hash (md5=5f4dcc3b5aa765d61d8327deb882cf99, sha1=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8) and is thus easy to identify in a password database.

With a salt, you have to compute a rainbow table for each salt you encounter. A good-sized salt, say 32 bits (ideally, 128 or even more), means you have to compute a rainbow table for every password you want to crack, thus largely defeating its purpose.

这篇关于为什么我们使用“盐”确保我们的密码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆