结论:SHA-1对抗预像攻击是安全的,但易于计算,这意味着更容易进行暴力破解或字典攻击(SHA-256等后继哈希函数也是如此)。根据情况,设计为计算复杂的哈希函数(如bcrypt)可能是更好的选择。
有些人经常说"SHA-1已经被破解了",所以我想了解这到底是什么意思。假设我有一个SHA-1密码哈希的数据库,并且攻击者使用最先进的SHA-1破解算法和拥有10万台机器的僵尸网络获得了访问权限。(控制10万台家用计算机意味着他们可以每秒执行大约10^15次操作)。
- 找到任何一个用户的密码需要多长时间?
- 找到给定用户的密码需要多长时间?
- 找到所有用户的密码需要多长时间?
- 找到一种作为其中一个用户登录的方法需要多长时间?
- 找到一种作为特定用户登录的方法需要多长时间?
如果密码被加盐,情况会怎样变化?加盐的方法(前缀、后缀、两者都有,或者更复杂的异或等)是否重要?
在经过一番搜索后,这是我的当前理解。如果我误解了什么,请在答案中纠正。
- 如果没有盐值,彩虹表攻击可以立即找到所有密码(除了极长的密码)。
- 如果存在足够长的随机盐值,最有效的找出密码的方法是暴力破解或字典攻击。既不是碰撞攻击也不是原像攻击有助于找出实际密码,因此对 SHA-1 的密码学攻击在这里没有帮助。使用什么算法甚至并不重要 - 甚至可以使用 MD5 或 MD4,密码也同样安全(因为计算 SHA-1 哈希会慢一些,所以还是有一点区别的)。
- 为了评估“同样安全”的安全性,假设单次 sha1 运行需要 1000 次操作,并且密码包含大写字母、小写字母和数字(即,60 个字符)。这意味着攻击者每天可以测试 10156060*24 / 1000 = 约 1017 个可能的密码。对于暴力破解攻击来说,这意味着在 3 小时内测试所有不超过 9 个字符的密码,在一个星期内测试不超过 10 个字符的密码,在一年内测试不超过 11 个字符的密码。(每增加一个字符,所需时间就要增加 60 倍。)字典攻击要快得多(即使是一个单独的计算机攻击者也可以在几个小时内进行),但只能找到弱密码。
- 为了登录用户,攻击者不需要找出确切的密码;找到一个产生相同哈希值的字符串就足够了。这被称为第一原像攻击。据我所知,没有对 SHA-1 的原像攻击。(暴力破解需要 2160 操作,这意味着我们理论上的攻击者需要 1030 年才能完成。理论可能性的极限约为 260 操作,攻击需要几年的时间。)有针对缩小版本 SHA-1 的原像攻击,但影响微乎其微(对于使用 44 步而不是 80 步的缩小版 SHA-1,攻击时间从 2160 操作降至 2157)。有针对 SHA-1 的碰撞攻击是在理论可行范围之内的(最好的攻击将时间从 280 减少到 252),但即使没有盐值,这些攻击也对密码哈希毫无用处。
更新:Marcelo指出了一篇文章,提到在2的106次操作中进行第二前像攻击。(编辑:正如Thomas解释的那样,这种攻击是一种假设构造,不适用于现实场景。)尽管如此,我仍然看不出这对于将SHA-1用作密钥派生函数构成危险。是否有普遍的好理由认为碰撞攻击或第二前像攻击最终可以被转化成第一前像攻击?