这几天AcFun数据库泄露的消息一大早就沸沸扬扬地传开了,所幸从AcFun的公告里可以看出泄露的用户密码均经过「加密」(实际上指哈希),所以我们仍然是安全的。
网站安全代码
从泄露出的部分信息可以看到,在存储密码这件事上,AcFun并没有犯什么低级错误,加之道歉诚恳,很多人表示「选择原谅」。
合格的后端开发者和运维人员需要考虑每个接口的安全性、每个可被公网访问到的服务器的安全性,保证不要犯错。但是我们还需要考虑,如何在已经犯错的情况下把损失降低到最小。在做数据的存储方案时,我们需要假设储存的数据已经被泄露出去了,如用户密码这种隐私数据的存储就是一个重点。
讲密码的存储方案前,先要记住三条前提:
1.用户喜欢到处使用一样的密码用户
2.用户喜欢喜欢使用简单好记的密码
3.世界上没有绝对的安全,但当攻击成本远高于收益时,整个系统达到相对安全
明文存储?
即使仅从道德的角度来说,后端也不应该以明文形式存储用户密码。
2011年CSDN密码泄露事件和2016年的网易52G事件出现后,比他们数据库被盗这件事更令人震惊的是,他们泄露的数据库里的密码居然全部都是明文。
明文存储的方法将安全性全部下放给了运维人员、开发人员和管理人员:
1.从运维层面看,任何操作系统漏洞、基础工具漏洞的发生,都会导致密码泄露
2.从开发层面看,任何代码逻辑有漏洞、任何依赖库的漏洞都可能导致密码泄露
3.从管理层面看,任何一个有权限读取数据库的人,都能看到所有用户的密码
由于前提1(大家总是到处使用一样的密码),所以明文密码泄露之后,再使用撞库攻击,还能得到其他网站的用户密码,对用户造成更严重的危害。比如2014年的12306密码泄露事件里,12306并没有犯错,只是黑客收集了很多其他网站的明文账号密码,再去12306批量尝试登陆,就可以得到大量用户的12306信息。
所以,后端不应该以任何明文或可以转换回明文(如可逆的加密)的形式储存密码。由于储存的信息并不是明文,所以大多数网站的「找回密码」功能并不能真的告诉你密码,只能让你重新设置一次。如果你发现一个网站的「找回密码」功能真的找回了你的密码,那就要当心你密码的安全性了。
做个哈希?
要保存密码的某种可被验证的形式,又要让保存的数据「不可逆」,首先能想到的就是哈希了。
十年前,大多数网站保存的都是经过一次MD5哈希的密码。哈希保存的思路很简单:用户注册时,把他的密码做一次MD5运算储存起来;用户登录时,把他输入的密码做一次MD5运算,再验证是否和数据库里储存的一致。
在MD5被证明不够安全以后,大家又开始选择其他的哈希算法如sha256等。但除了哈希算法本身的安全性外,这种做法的缺陷很快暴露,就是应付不了彩虹表的攻击方式。