一般的,我们在后端保存密码时,不会使用明文进行保存,明文保存意味着数据库被爆的损失将直线型上升,例如CSDN密码泄露事件,常见的方式是加盐操作,所谓的盐(salt)是一个随机数,算法演示入:MD5(MD5(P) + salt)SHA1(MD5(P) + salt)MD5(P + salt)等。

分析

但这种方式到如今,基本上都说是不安全的加密方式,这让我在使用的过程中,不免出现一些担心,这需要进行更换加密方式么,它为什么不安全呢?

在上述操作后,服务器保存的是H = MD5(MD5(P) + salt)中的H,这样会避免即使服务器因为某些原因,数据库泄露导致实际密码被泄露,这里也就是利用了哈希函数运算不可逆的特性。

1561347903109

但存在暴力破解的可能性,因为用户保存密码的方式是有迹可循的,例如生日,数字简单循环密码(123456),简单英文密码(qwert),事实上也确实存在这样一张常见密码的表,攻击者若还能拿到盐salt,就可以尝试各种哈希来得到这样的一张密码对照表。过程相对简短,但其中有两个难点,第一:如何拿到盐?第二:确定哈希函数。

在实际的操作中,方法总比困难多,例如,随机盐的存储一般是和用户信息一起放在数据库中的,那也就以为着,爆破掉数据库,就有可能把盐给一锅端,但同时攻击者需要做的是,每一个盐所产生的对应表并不能套到其他盐的身上,需要根据每个盐都来进行计算。

这时候就有另一种方案提出,加固定盐,这也就意味着,盐是唯一的,被生成在代码中,并不会随着暴库被偷走,但这时有另外一个问题,那就是:
攻击者已经攻破我们的系统进入到内部,也就意味他不进能偷走我们的数据库;
也意味着他能够获取到我们的软件运行文件;
那也就是意味着,若是攻击者对我们的软件进行分析,找到我们的密码验证的函数;
然后一顿分析,是有可能拿出我们的的,那攻击者只需要得出一套密码对照表,就能完全对应我们所有的密码信息。

更进一步

在需要更强的密码存储中,我所了解到的,一般会推荐PBKDF2bcrypt之类似的算法,不过这类算法,运行成本对于攻击者来说,是比较高的,没有足够的利益,是不会激起他们的兴趣的,但相对的,对于我们的运算成本也增加了,算是以时间成本来换取安全的方式。

还有就是既然是为了增加攻击者破解的难度,那就多使用哈希函数反复计算,这个其实和上述的算法类似。

我的理解

在各种加密方式中,我在选择中,我会选择MD5(SHA1)加随机盐的方式来保存我的后端密码,对于这样的保存方式,在应对中小型网站的存储密码需要中,我觉得是足够了,足以保证数据的相对安全,同时其计算成本也足以保证我的用户密码的安全性,若是测试部门等有关部门对我的选择报以怀疑,这时,我会加上提醒用户不使用类似123456qwerty等简单密码,且帮助(强制)用户使用字母、数字等混合密码来保证密码的安全性。

在实际的密码存储中,我记起一句话,抛开业务来谈技术都是耍流氓,不是银行,淘宝等场景下,非得弄个绝对防御,结果保护的也就是些name,发言等一些无关痛痒的数据,这就有点高射炮打蚊子了。所以在这种情况下,MD5(SHA1)加随机盐的方式造成的破解难度,以及网站数据的价值,已经让绝大多数的攻击者难以提起兴趣攻击我们的网站(毕竟人都是要恰饭的嘛)。


参考: 没知识真可怕——应用密码学的笑话之MD5+Salt不安全