最近几年的新闻中一直有互联网头部公司系统被攻击导致用户密码泄露的新闻。那密码被破解肯定和当初项目伊始时选择的密码哈希方案造成的历史包袱有关。我们不讨论这些互联网巨头应该采用什么方案防止用户密码被破解,我知道的方案人家养的那些技术大拿更知道了。我们就来说一下,如果我们有机会自己从零开始做一个系统时,应该选择什么样的哈希算法有效防止用户的密码不被破解。
既然想保护用户密码不被破解,就先了解下破解密码的手段吧。
攻击密码的主要方法
我们需要防御的两种主要的密码攻击方式是:
- 字典攻击
- 暴力攻击
它们的工作方式非常简单:使用预先生成的密码哈希列表并进行简单的比较,以找到创建所需哈希的字符串。对于未加盐的密码,可以下载大量预先生成的密码列表。然后只需要简单查找即可。这种列表称被为彩虹表。
如果密码使用了盐,但没有为每个密码使用唯一的盐,那么攻击者要做的就是手动生成彩虹表,对每个组合使用盐,然后进行查找。如果你对每个密码使用唯一的盐,则攻击者需要针对每个密码为每个组合生成一个列表再去查找。这是另外一种类型的攻击,即暴力攻击。
暴力攻击通过反复尝试猜测密码来破解密码。与慢速哈希(例如bcrypt
,scrypt
和pbkdf2
)不同,MD5
或SHA-1
(或SHA-256
,SHA-512
等)是消息摘要算法,它们旨在快速验证给定消息是否未被篡改。
一个常见的示例是验证下载的文件。下载文件后,在文件上运行MD5
,然后将哈希与原始站点提供的哈希进行比较验证文件是否被篡改过。所以MD5
,SHA-1
这些算法不是为密码设计的。因为这些算法的哈希速度会随着硬件计算能力的提升一起提升,如果你使用了这些算法做密码哈希,那么不论密码加没加盐,加盐后做了几次哈希,破解密码的的时间都会随着计算机硬件的提升越来越短。
哈希算法速度比对
在2012年的演讲中,Jeremi M. Gosney
使用商业级硬件测试比对了各种哈希算法的性能。该测试使用五台服务器,并带有18个消费级显卡:
- 10x HD 7970
- 4x HD 5970 (dual GPU)
- 3x HD 6990 (dual GPU)
- 1x HD 5870
得出的结果如下:
鉴于硬件的进步速度,我们应该期望今天使用相同的硬件的花费会大大降低,或者使用今天的硬件,性能会比2012年时提高大约6-8倍。
上面的图表里的结果显示如果你(2012年)仍在使用未加盐(或非唯一)的MD5
哈希值作为密码,那么2012年使用此配置硬件的的攻击者每秒可以进行180,000,000,000次哈希。即使是最复杂的SHA
算法(SHA-512
),其速度比MD5
慢49,000,000倍,但每秒也可以计算36.4
万次哈希。
另一方面,bcrypt
每秒仅能执行71,000次哈希。这比MD5
慢253,500,000%,比SHA-1
慢88,700,000%,甚至比SHA-512
慢412%。
总结
很多系统中在存储用户的密码前会对密码加盐并增加密码哈希的次数,以减慢密码暴力攻击的速度。例如执行五次MD5
迭代,但即使是这样仍然只能使尝试破解次数减少到每秒36,000,000,000次,是单个SHA-1
的两倍,并且仍然比SHA-512
快99.99898%,而使用bcrypt
则要慢443,000,000%。所以bcrypt
是一种很好的散列密码解决方案,可以有效地防止暴力破解和字典攻击。
下一篇文章我们将展示,在Go
语言写的项目里如何使用bcrypt
进行密码哈希。
参考链接
近期文章推荐
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。