evol128[Blog]

I am the bone of my code

如何正确加密用户密码

vim 系列很可能要坑掉了。。。Orz

很久很久以前,当人们还没有什么安全概念的时候,密码都是不加密存储。这样显然会带来很严重的问题,当你的服务器受到攻击时,用户的密码有非常非常大的概率会泄露出去,这样会给用户带来很严重的问题(参考csdn事件= =)

后来,大家觉得明文存密码太傻X了(工信部的那群**还没有这么觉得= =),于是要把密码加密,最早用的是对称加密法,就是用一个key去加密密码,然后只存储密文,用户验证时候,用同样的key解密密文就可以得到原文了。

不久以后,这个方法还是被大家觉得不太靠谱,毕竟那么多用户,用的都是同一个key,万一key泄露出去了,一样得玩完儿。那么,有没有不用key的加密方式呢?有的,one way hash。简单来讲,就是把用户密码通过不可逆的hash function映射到一个密文上。因为这个hash function的映射区间很大(当前应用比较多的是128或256bit),所以极少会发生两个不同的密码映射到同一个密文的情况。而且,因为这个hash function是不可逆的,即使有人黑掉了数据库,他仍然不知道用户的密码是什么。非要说缺点的话,就是没法帮用户“找回密码”,一般只能重新设一个。因为这个方法极大地提高了密码存储的安全性,所以这点不便就无视吧。(btw,如果哪个网站有找回密码的功能,我强烈建议大家不要再用了。。。)

故事就到这里完了?才不会呢!!!你太小看现在的黑客了!!!虽然上面那个方法看似无懈可击,但是,因为加密算法是固定的(不要试图隐藏你的算法,这是非常不靠谱的),黑客们只要花足够多的时间,就可以列出一张明文-->密文的映射表,再加上类似rainbow-table技术加速查表。一旦有人把表给列出来了,那么不管你的加密算法多么牛X,一样给破解了。不过解决方法也蛮简单的,为每个用户都随机生成一个128位的字符串,叫它salt好了,加密的时候把用户密码和salt一块儿加密,就是说,hash(password+salt)。因为这个salt是随机的,黑客得为每一个salt都写一个rainbow table,这在时间和空间上是不可能做到的,ok,safe!

很遗憾,最近几年,事情又有了变化,由于现在3d游戏市场发展的太快了,intel和nvidia研究出了各种功能强大的gpu。gpu和cpu最大的不同在于,它能够以非常快的速度进行某些算术运算。于是乎,就有人拿gpu来代替cpu来进行暴力破解了。不要觉得这没什么大不了,根据统计数据,现在主流的sha256加密算法(md5 died),原本需要1年时间破解的密码,现在用gpu只需要1个月!破解速度快了10倍多!这下真没辙了,毕竟是用的暴力破解,光增加密文长度没用,又不能强迫用户增加密码长度。。。不过呢,也别觉得压力大,现在已经有不少人着手开发了没法用gpu优化的算法,譬如说这个pbkdf2算法。

如果上面的方法还不够的话,我们还有一些物理手段来加密,譬如说令牌(不是工商银行那种纸牌)。

我最不擅长写总结了,不过还是说一些吧。这世上没有绝对安全的算法,你甚至没法证明它是安全的(证明加密算法安全,实质就是证明NP问题)。只要一个算法还没有被人成功破解,我们就可以继续信任它。只是,我希望大家在build application的时候,能够注意到这一点,毕竟,用户资料的安全,可是很重要的呢~