如何安全的存储用户密码

1、明文存储(极不推荐)

  • 这种设计思路非常简单,但是缺陷也非常明显,数据库一旦泄露,那么所有用户名和密码都会泄露,后果非常严重。

2、使用MD5或其它算法哈希后存储(较不推荐)

  • MD5算法的原理可简要的叙述为:MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
  • 假如你设置的密码是123456,使用MD5后那数据库中存储的就是4QrcOUm6Wau+VuBX8g+IPg==,当用户登陆的时候,会把用户输入的密码执行MD5后再和数据库就行对比,判断用户身份是否合法,这种加密算法称为散列(哈希)。
  • 但是这种方式使用同一个密码进行哈希得到的密文始终是一样的,考虑到多数人所使用的密码为常见的组合,攻击者可以将所有密码的常见组合进行单向哈希,得到一个密文组合,然后与数据库中的摘要进行比对即可获得对应的密码,这个密文组合也被称为彩虹表(rainbow table)。

3、加盐后哈希存储(较推荐)

通过在密码任意固定位置插入特定的字符串,使其不再是人们常用的组合,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。用户密码+salt之后,进行哈希散列,再保存到数据库,数据库同时存储MD5值和salt盐值,验证正确性时使用salt进行MD5即可,这样可以有效应对彩虹表破解法。使用加盐,需要注意一下几点:

  • 不能在代码中写死盐,且盐需要有一定的长度(盐写死太简单的话,可能被注册几个账号反推出来)
  • 每一个密码都有独立的盐,并且盐要长一点,比如超过 20 位。(盐太短,加上原始密码太短,容易破解)
  • 最好是随机的值,并且是全球唯一的,意味着全球不可能有现成的彩虹表给你用。

4、使用BCrypt算法加密后存储(非常推荐)

  • 即使是加了盐,密码仍有可能被暴力破解,因此,我们可以采取更慢一点的算法,让黑客破解密码付出更大的代价,甚至迫使他们放弃。BCrypt生而为保存密码设计的算法,相比 MD5要慢很多。BCrypt比MD5慢几十倍,黑客想暴力破解的话,就需要花费几十倍的代价,因此一般情况,建议使用Bcrypt来存储用户的密码。
  • 常见的加密算法MD5只要是相同的salt和原密码,加密后产生的密串都是一致的,而对于BCrypt算法,使用相同的明文,每次生成的新的加密字符串都不一样

5、Spring Boot中使用jbcrypt对明文进行加密

当然我们也可以使用Spring Security中的BCryptPasswordEncoder进行加密,不过使用方法需要引入Spring Security框架,造成项目臃肿。此外,只要在pom.xml文件中导入Spring Security依赖,如果不进行配置,整个项目的接口请求路径都会被拦截,如果只是想单纯的使用BCrypt算法将密码进行加密,更加轻量且无需配置的jbcrypt是更好的选择。

  • 5.1 在pom.xml中导入maven依赖
<dependency>
    <groupId>org.mindrot</groupId>
    <artifactId>jbcrypt</artifactId>
    <version>0.4</version>
</dependency>
  • 5.2 新建并编写JbcryptUtil工具类
import org.mindrot.jbcrypt.BCrypt;

public class JbcryptUtil {

    /**
     * @param password 明文密码
     * @return 加密后的密码
     * @Description 对明文密码进行加密, 并返回加密后的密码
     */
    public static String encode(String password) {
        return BCrypt.hashpw(password, BCrypt.gensalt());
    }

    /**
     * @param rawPassword     明文密码
     * @param encodedPassword 加密后的密码
     * @return boolean
     * @Description 将明文密码跟加密后的密码进行匹配,如果一致返回true,否则返回false
     */
    public static boolean match(String rawPassword, String encodedPassword) {
        return BCrypt.checkpw(rawPassword, encodedPassword);
    }
}
  • 5.3 在注册的时候调用encode()方法将加密后的密码存储到数据库中,登录的时候调用match()方法将用户输入的密码与数据库中存储密码进行匹配验证
    在这里插入图片描述
    在这里插入图片描述
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值