密码存储那些事

最近在用koa2写一个服务用来负责用户数据存储与身份验证,然后写着写着突然对密码存储有点兴趣,所以花了点时间研究了一下。

哈希加密

经历了那么多的密码泄露事件后,现在常用的加密方式至少也会使用MD5处理以后再保存了吧。而像MD5这种哈希加密算法对于密码加密来说优点在于不可逆。也就是说加密后的数据是无法逆向恢复原始数据的。

我们先来看一个可逆的例子,a + b = c。如果我们知道b和c那么就很轻松的知道了a,这种是可逆算法。

而如果有一个算法F(),F(a) = F(d) = c。那么即使你知道了c和算法F,你也不知道到底刚刚运算的是a还是d,这就导致的不可逆。但是每次你计算F(a)都会得到结果c。所以F是一种单向计算的算法,也就是类似于MD5的算法。MD5计算过程中会丢失信息,最后得到一段摘要信息。

此时我们如果要对密码做哈希加密,那么尽可以使用这段加密信息进行存储。即使我们的数据库被泄露,也不会直接泄露掉明文的密码。恩,请注意是不会直接泄露掉密码。

加盐

请注意上一段中被加粗的直接,因为理论上它是可以被攻击的,例如彩虹表等攻击方法,可以使用彩虹表对密码进行暴力破解。彩虹表是一系列用户常用密码表的MD5或其他加密算法的映射表。如果能够拿到数据库,可以直接通过彩虹表快速查找出大部分用户的真实密码。

此时我们就可以利用加盐的方法来对密码进一步加密。加盐其实就是说,在一段密码被加密前加入一段随机字符串,然后加密拼接后的字符串存储到数据库,这段被加入的随机字符串就被称之为盐。

一般来说破解数据库一定是一种会使破解人获利的行为才会促使人们去破解数据库。而如果破解数据的成本高于其破解完成后可以获取的利益的时候,那么这个数据就可以被我们认为是安全的。之前说过彩虹表的破解方法,它其实是使用了一系列常用密码然后生成了很大的加密数据MAP库,很常见的用空间换时间的方式。

而对于数据库破解而言,成本其实最主要的就是时间。当我将用户密码加盐以后,首先数据库中存放的密码并不是用户常用密码加密后的内容,而是加入了随机字符串后加密生成的,很难通过常规的彩虹表破解。此时就需要针对每一个盐字符串生成一份彩虹表才能对特定密码进行破解。而彩虹表的生成对于破解者来说绝对是个噩梦。此时就会产生巨大的时间和计算的成本。这样就有效的保证了数据的安全。

还有很常见的方式就是通过延长加密解密的时间来增加彩虹表生成的时间,增加破解成本。