开题我想问大家,在做项目的时候你们都用过什么加密算法,比如在做用户登录的时候,你是怎么样把用户的重要信息加密起来的?

如果我没猜错的话,md5应该是大家的首选,其次应该就是sha256之类的。但我要告诉你,这些其实都不能叫做加密算法呢?

实际上,md5叫做摘要算法,也叫做哈希函数,哈希函数可以将无限键值空间中的所有键都均匀地映射到一个指定大小的键值空间中;一个好的摘要算法能够帮助我们保证文件的完整性,避免攻击者的恶意篡改,但是加密算法或者加密的功能是 —— 通过某种特定的方式来编码消息或者信息,只有授权方可以访问原始数据,而没有被授权的人无法从密文中获取原文。说白了md5不可逆,但是加密是一种可逆的过程。由于加密需要同时保证消息的秘密性和完整性,所以加密的过程使用一系列的算法,md5 确实可以在加密的过程中作为哈希函数使用来保证消息的完整性,但是我们还需要另一个算法来保证消息的秘密性,所以由于 md5 哈希的信息无法被还原,只依靠 MD5 是无法完成加密的。所以以后不要再讲用md5加密了,并且这是一个危险的过程。

什么是彩虹表

彩虹表是一个用于加密散列函数逆运算的预先计算好的表, 为破解密码的散列值(或称哈希值、微缩图、摘要、指纹、哈希密文)而准备。一般主流的彩虹表都在100G以上。 这样的表常常用于恢复由有限集字符组成的固定长度的纯文本密码。这是空间/时间替换的典型实践, 比每一次尝试都计算哈希的暴力破解处理时间少而储存空间多,但却比简单的对每条输入散列翻查表的破解方式储存空间少而处理时间多。(来自百度百科)

如果当不法分子拿到我们的内部数据,便可以通过彩虹表一类的预计算表中存储的映射来查找原始密码,那么如何解决这种问题呢,百度百科还说:”使用加salt和KDF函数可以使这种攻击难以实现“,我们只讨论前者不讨论后者(后者涉及到密码学鄙人不才没学过)。利用salt(加盐)的方式可以有效的降低彩虹表映射成功的概率,并增高其运算成本。由于每个密码都使用了随机的盐进行哈希,所以预先计算的彩虹表就没有办法立刻破译出哈希之前的原始数据,攻击者对每一个哈希都需要单独进行计算,这样能够增加了攻击者的成本,减少原始密码被大范围破译的可能性。

bcrypt

虽然哈希加盐的方式确实能够增加攻击者的成本,但是今天来看还远远不够,我们需要一种更加安全的方式来存储用户的密码,这也就是今天被广泛使用的 bcrypt,使用 bcrypt 相比于直接使用哈希加盐是一种更加安全的方式,也是我们目前推荐使用的方法,为了增加攻击者的成本,bcrypt 引入了计算成本这一可以调节的参数,能够调节执行 bcrypt 函数的成本。

当我们将验证用户密码的成本提高几个数量级时,攻击者的成本其实也相应的提升了几个数量级,只要我们让攻击者的攻击成本大于硬件的限制,同时保证正常请求的耗时在合理范围内,我们就能够保证用户密码的相对安全。bcrypt 这一算法就是为哈希密码而专门设计的,所以它是一个执行相对较慢的算法,这也就能够减少攻击者每秒能够处理的密码数量,从而避免攻击者的字典攻击。

func main() {
for cost := 10; cost <= 15; cost++ {
startedAt := time.Now()
bcrypt.GenerateFromPassword([]byte("password"), cost)
duration := time.Since(startedAt)
fmt.Printf("cost: %d, duration: %v\n", cost, duration)
}
}

$ go run bcrypt.go
cost: 10, duration: 51.483401ms
cost: 11, duration: 100.639251ms
cost: 12, duration: 202.788492ms
cost: 13, duration: 399.552731ms
cost: 14, duration: 801.041128ms
cost: 15, duration: 1.579692689s

运行上述 代码片段 时就能发现 cost 和运行时间的关系,算法运行的成本每 +1,当前算法最终的耗时就会翻一倍,这与 bcrypt 算法的实现原理有关,你可以在 Wikipedia 上找到算法执行过程的伪代码,这可以帮助我们快速理解算法背后的设计。

如果硬件的发展使攻击者能够对使用 bcrypt 存储的密码进行攻击时,我们就可以直接提升 bcrypt 算法的 cost 参数以增加攻击者的成本,这也是 bcrypt 设计上的精妙之处,所以使用 bcrypt 是一种在存储用户密码时比较安全的方式。抵御攻击者的攻击的方式其实就是提高单次算法运行的成本,当我们将用户的验证耗时从 0.1ms 提升到了 500ms,攻击者的计算成本也就提升了 5000 倍,这种结果就是之前需要几小时破解的密码现在需要几年的时间。

不论如何,使用 MD5、MD5 加盐或者其他哈希的方式来存储密码都是不安全的,那么我们真正的加密算法是什么样子的呢?他都有多少种类和多少种加密方法,在我们的日常生活中如何使用呢,请移步《md5算加密吗?(非)对称加密算法又是什么(二)》观看。

参考文章:https://draveness.me/whys-the-design-password-with-md5