security - 为什么盐会造成字典攻击 'impossible' ?

标签 security hash salt dictionary-attack

更新:请注意,我不是在问什么是盐、什么是彩虹表、什么是字典攻击或盐的目的是什么。我想问:如果你知道用户的salt和hash,是不是很容易算出他们的密码?

我理解这个过程,并在我的一些项目中自己实现它。

s =  random salt
storedPassword = sha1(password + s)

在您存储的数据库中:

username | hashed_password | salt

我见过的每个加盐实现都会在密码末尾或开头添加盐:

hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)

因此,来自名副其实的黑客的字典攻击(哈哈)只需针对上面列出的常见组合中存储的盐运行每个关键字即可。

上面描述的实现肯定只是为黑客增加了另一个步骤,而没有真正解决根本问题?有什么替代方法可以解决这个问题,或者我误解了这个问题?

我唯一能想到的就是使用一种 secret 混合算法,以随机模式将盐和密码组合在一起,或者将其他用户字段添加到哈希过程中,这意味着黑客必须有权访问数据库并且代码将它们与字典攻击结合起来,证明是卓有成效的。 (更新,正如评论中指出的那样,最好假设黑客可以访问您的所有信息,因此这可能不是最好的)。

让我举一个例子,说明我建议黑客如何使用密码和哈希值列表来破解用户数据库:

来 self 们被黑客入侵的数据库的数据:

RawPassword (not stored)  |  Hashed   |     Salt
--------------------------------------------------------
letmein                       WEFLS...       WEFOJFOFO...

常用密码字典:

   Common Password
   --------------
   letmein
   12345
   ...

对于每个用户记录,循环通用密码并对它们进行哈希处理:

for each user in hacked_DB

    salt = users_salt
    hashed_pw = users_hashed_password

    for each common_password

        testhash = sha1(common_password + salt)
        if testhash = hashed_pw then
           //Match!  Users password = common_password
           //Lets visit the webpage and login now.
        end if

    next

next

我希望这能更好地说明我的观点。

给定 10,000 个常用密码和 10,000 条用户记录,我们需要计算 100,000,000 个哈希值才能发现尽可能多的用户密码。这可能需要几个小时,但这并不是什么问题。

破解理论更新

我们假设我们是一个腐败的网络主机,可以访问 SHA1 哈希值和盐的数据库,以及混合它们的算法。数据库有10,000条用户记录。

This site声称能够使用 GPU 每秒计算 2,300,000,000 个 SHA1 哈希值。 (在现实世界的情况下可能会慢一些,但现在我们将使用引用的数字)。

(((95^4)/2300000000)/2)*10000 = 177 seconds

给定 95 个可打印 ASCII 字符的全范围,最大长度为 4 个字符,除以计算速率(变量),再除以 2(假设发现密码的平均时间平均需要 50% 的排列) )对于 10,000 个用户,计算出长度 <= 4 的所有用户密码需要 177 秒。

让我们稍微调整一下以使其更真实。

(((36^7)/1000000000)/2)*10000 = 2 days

假设不区分大小写,密码长度 <= 7,仅包含字母数字字符,则需要 4 天才能解决 10,000 条用户记录,并且我将算法的速度减半以反射(reflect)开销和非理想情况。

重要的是要认识到这是一种线性暴力攻击,所有计算都是相互独立的,因此这是一个需要多个系统来解决的完美任务。 (IE 很容易设置两台计算机从不同端运行攻击,这将减少一半的执行时间)。

考虑到对密码进行递归散列 1,000 次以使此任务的计算成本更高的情况:

(((36^7) / 1 000 000 000) / 2) * 1000 seconds = 10.8839117 hours

这表示最大长度为 7 个字母数字字符,一个用户的执行速度低于引用数字的一半。

递归散列 1,000 次可有效阻止全面攻击,但针对用户数据的针对性攻击仍然容易受到攻击。

最佳答案

它并不能阻止字典攻击。

它的作用是阻止那些设法获取您的密码文件副本的人使用 rainbow table从哈希值中找出密码。

不过,最终它可能会被暴力破解。该部分的答案是强制您的用户不要使用字典单词作为密码(例如,至少需要一个数字或特殊字符)。

更新:

我应该早先提到这一点,但一些(大多数?)密码系统对每个密码使用不同的盐,可能与密码本身一起存储。这使得单个彩虹表毫无用处。 UNIX crypt 就是这样的库可以工作,现代类 UNIX 操作系统已经使用新的哈希算法扩展了该库。

我知道,较新版本的 GNU crypt 添加了对 SHA-256 和 SHA-512 的支持。

关于security - 为什么盐会造成字典攻击 'impossible' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3566504/

相关文章:

hash - 和弦协议(protocol)。分布式哈希表 (DHT)。点对点。 (点对点)

c++ - 如何将字符串添加到布谷鸟过滤器?

php - 在登录 PHP MySql 时检索加盐 MD5 密码

php - Symfony2 Twig 安全策略

c# - C# Windows 应用程序中的密码散列,缺少 ASP.NET 的 FormsAuthentication?

security - 在 Spring Security 3.1 中,StandardPasswordEncoder 最适合用于加盐密码的用途是什么?

php - 生成/存储/读取安全 MCRYPT 盐

php - 安全性:用户能够命名 session 变量会出现什么问题?

android - 使用 Android 12knownSigner 保护级别标志

windows - 剪贴板是否在 Windows 下的桌面之间共享?