「密码」这种敏感信息,到底该如何存储?

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 「密码」这种敏感信息,到底该如何存储?


最近接手公司一个之前的服务,竟然发现用户密码是明文存储在数据库中!

说实话还是有点吃惊的,这至少也得搞个 MD5 存一存吧。

不过 MD5 其实也没啥用,今天我们就来盘盘密码这种敏感信息该如何存储。

数据库为什么不能明文存储密码

不仅仅是为了防止系统管理员或者 DBA 等公司人员获得用户的密码,也是防止被黑客拖库产生更大的信息泄露。

如果黑客通过不法手段获取了服务的数据库存储信息,盗取里面的内容,从而直接获得明文密码,那么影响就会很大。

因为绝大部分人所有账户的密码都会设置成一样的,只要知道一个网站的明文密码后,基本上等于搞定这个用户其他网站的所有账号,也就是撞库。

所以不能明文存储密码,需要加密下。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

MD5 不是加密算法

实际上,经常有人会说拿MD5加密,这样说没问题,但是我们心里要清楚,MD5 压根就不是加密算法,它其实就是个摘要算法。

加密算法指的是把一段数据加密后,可以解密。

很明显 MD5 无法解密,只能暴力穷举破解,所以它不算是加密算法。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

为什么用 MD5 存储密码不好

大部分人的密码都会设置得比较简单,比如名字缩写加个出生日期这种。

而黑客其实会针对常见的一些密码,生成彩虹表。

彩虹表:是用于加密散列函数逆运算的预先计算好的表,常用于破解加密过的密码散列。(维基百科)

就像下面的表格:

这样一来只要准备得足够充分,彩虹表足够大,那么直接对比彩虹表就能反推得出明文密码,所以直接简单用 MD5 也是不安全的。

给密码加点盐

那咋办么?

其实彩虹表大部分能找到的只是常见的密码。

基于这点,我们虽然不能强迫用户设置一些非常复杂的密码(这记忆成本太高)。

但是我们可以手动给用户的密码拼接上一些复杂的字符,然后经过哈希函数处理之后落库。

比如用户初始密码是123456,我们可以给他的密码加点盐,盐其实就是一些复杂的字符数字,比如:

这样即使不法分子盗取到密码,预先准备的彩虹表也无用(因为密码变得不常见了),使得破解的成本变高。

这种盐叫固态盐,不需要落库存储,一般在代码或者配置中保存。一旦被不法分子试出这个盐,那么继而就能通过这个盐试出别的密码。

所以推荐动态盐,即让每个账号下密码加的盐都是不一样的,这样一来,不法分子的破解成本就更高了。

动态盐需要分别为每个用户记录对应密码加的盐值,一般是落库存储,比如上图所示在用户表上加个 salt 字段。

又或者直接跟密码拼一起中间用特殊符号切分等等,比如下图用 $ 来分割。(没错,动态盐是直接存储的,也就是说攻击者可以拿到每个账号的盐)。

我还看过一些方案,比如不加字段也不用分隔符,把用户的创建时间进行处理作为动态盐,等等。

加盐这种手段仅仅只是增加了攻击者的破解成本,因为攻击者知道盐值,从而就能反推出一个值,使得这个md5(值+盐) = md5(密码+盐)

因为不论这个值是否等于密码,反正只要最终 hash 的结果是一样的,就都能登录,所以攻击者要推是可以推出来的,只不过成本会高些。

总而言之,通过摘要算法来存储密码,不法分子是可以通过暴力、彩虹表、字典等方式来破解。

如果你仅仅是用 md5 处理密码存储,那么这些破解其实成本也不是很大。乍一说你可能没啥感觉,我在网上看到一个结论:md5 来存储 6 位长度的密码(仅仅包含小写和数字),只需要 40 秒,就可以穷举所有密码。

bcrypt

因此,为了进一步给黑客们增加破解成本,需要替换 md5 这类 hash 快速的方法,换成 bcrypt 这种算法。

md5 计算只需要 1 微秒,而 bcrypt 需要 0.3 秒,速度差了 30 万倍。

1 秒 = 1000000 微秒

因此,如果本来 40 秒就能破解的话,换成 bcrypt 后变成 138 天才能破解!

bcrypt 就是这么个哈希算法,它有个迭代次数,可以使得计算变慢,非常适合这种场景!

不用摘要算法,加密存储行吗?

其实还有一种防破解的方式,就是采用加密算法。

比如采用对称加密 AES,这样只要密钥不泄露,攻击者拖库拿到密码也完全破解不了!

但是反过来想,假设密钥被泄漏了,那就是白给,比破解上述的 hash(密码+盐)更轻松,连试试都不需要。

所以加密存储的话就得看你的密钥保不保得住了。

最后

大致方案就这么几种。动态盐其实已经 OK 了,不过算法尽量别用 md5,可以用 sha1、sha256 这些,因为 md5 其实已经被破解了。

这里的破解不是说通过 md5 可以反向推出明文,而是利用 md5 hash 后的值能快速地找到另一个值使得 md5 的结果一致。

好了,今天这篇就说这么多了,更多的可以自行上网查阅。

参考资料

md5 和 bcrypt 的速度对比出处:

https://coolshell.cn/articles/2078.html



相关文章
|
3月前
|
存储 安全 API
利用环境变量管理敏感信息
【10月更文挑战第16天】在软件开发中,环境变量是管理敏感信息如API密钥、数据库密码等的安全方式,避免了将这些信息硬编码在源代码中。本文介绍了环境变量的概念、优势及如何在应用中实施,包括本地开发、CI/CD流程和云服务中的应用,以及实战技巧和最佳实践。
|
3月前
|
存储 安全 算法
如何确保用户密码在存储和传输过程中的安全性?
【10月更文挑战第4天】如何确保用户密码在存储和传输过程中的安全性?
|
4月前
|
存储 安全 算法
如何确保用户密码在存储和传输过程中的安全性
如何确保用户密码在存储和传输过程中的安全性
|
5月前
|
存储 JSON Kubernetes
在K8S中,存储敏感信息方式有哪些?
在K8S中,存储敏感信息方式有哪些?
|
7月前
|
数据处理 数据安全/隐私保护
JeecgBoot 中如何对敏感信息进行脱敏处理?
数据脱敏即将一些敏感信息通过加密、格式化等方式处理,展示给用户一个新的或是格式化后的信息,避免了敏感信息的暴露。
70 1
|
8月前
|
存储 SQL 运维
揭秘如何通过日志服务实现个人敏感信息保护
【2月更文挑战第3天】阿里云日志服务SLS(Simple Log Service)为保护个人敏感信息提供了全面的数据安全策略。在数据采集阶段,客户端可以对包含敏感信息的日志进行AES加密后上报至SLS中心Logstore,利用HTTPS加密链路保障传输安全。在存储环节,SLS支持对敏感字段进行专门的脱敏处理,如替换、哈希或截断等手段,确保原始敏感信息不被明文暴露。对于需要使用日志数据的业务方,SLS允许在分发前对敏感数据进行解密并再次脱敏,以满足合规性和安全性要求。通过精细的权限管理和审计功能,SLS可记录所有访问和操作日志,确保任何对敏感数据的操作都可追溯。
替换文件中的敏感信息
假设我们有一份文件,文件中包含了很多个人信息。现在需要一份去除其中敏感信息的版本,将文件中所有手机号的4~7位和身份证号的6~15位用 * 替换。
|
存储 安全 算法
在日常开发中,敏感数据应该如何保存或传输
说到敏感信息,第一个想到的恐怕就是用户密码了吧。攻击者一旦获取到了用户密码,就会登录用户的账号进行一系列操作。甚至有些用户还习惯不管什么应用都用同一个密码,导致攻击者可以登录用户全网账号。
|
安全 Ubuntu Linux
信息泄漏时代,如何让自己的密码更安全?
信息泄漏时代,如何让自己的密码更安全?
179 0