springsecurity密码加密

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>3.2.3.RELEASE</version>
</dependency>

 

BCryptPasswordEncoder相关知识:

用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。

特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。

BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。

import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class Test {

    public static void main(String[] args) {
        // springsecurity 注册加密方法
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode("1");
        System.out.println(encode);
        //$2a$10$H2HTe3SVdKMk8ewC3gRKouva7U6DAQspHqyhcdg805JGHAApV1Wci
        //$2a$10$Iz4Y52GmirUf5SRW6jTIA.0cgaS0mKTYZVN2cFFeK8DXk9YHVhJDW

        // springsecurity 登录加密方法
        BCrypt bCrypt = new BCrypt();
        String hashpw = bCrypt.hashpw("1", "$2a$10$Iz4Y52GmirUf5SRW6jTIA.0cgaS0mKTYZVN2cFFeK8DXk9YHVhJDW");
        System.out.println(hashpw);
    }

}

 

为什么要加密

2011年12月21日,有人在网络上公开了一个包含600万个CSDN用户资料的数据库,数据全部为明文存储,包含用户名、密码以及注册邮箱。事件发生后,CSDN在微博、官方网站等渠道发出了声明,解释说此数据库是2009年备份所用的,因不明原因泄露,已经向警方报案,后又在官网发出了公开道歉信。在接下来的十多天里,金山、网易、京东、当当、新浪等多家公司被卷入这次事件中。整个事件中最触目惊心的莫过于CSDN把用户密码明文存储,由于很多用户是多个网站共用一个密码,因此一个网站密码泄露就会造成很大的安全隐患。有了这么多前车之鉴,我们现在做系统时,密码都要加密处理。

加密方案

密码加密一般会用到散列函数,又称散列算法、哈希函数,这是一种从任何数据中创建数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来,然后将数据打乱混合,重新创建一个散列值。散列值通常用一个短的随机字母和数字组成的字符串来代表。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据会使得数据库记录更难找到。我们常用的散列函数有MD5消息摘要算法、安全散列算法(Secure HashAlgorithm)。

但是仅仅使用散列函数还不够,为了增加密码的安全性,一般在密码加密过程中还需要加盐,所谓的盐可以是一个随机数,也可以是用户名,加盐之后,即使密码明文相同的用户生成的密码,密文也不相同,这可以极大地提高密码的安全性。但是传统的加盐方式需要在数据库中有专门的字段来记录盐值,这个字段可能是用户名字段(因为用户名唯一),也可能是一个专门记录盐值的字段,这样的配置比较烦琐。Spring Security提供了多种密码加密方案,官方推荐使用BCryptPasswordEncoder,BCryptPasswordEncoder使用BCrypt强哈希函数,开发者在使用时可以选择提供strength和SecureRandom实例。strength越大,密钥的迭代次数越多,密钥迭代次数为2^strength。strength取值在4~31之间,默认为10。

一般情况下,用户信息是存储在数据库中的,因此需要在用户注册时对密码进行加密处理,代码如下:

@Service
public class RegService {

    /**
     * 一般情况下,用户信息是存储在数据库中的,因此需要在用户注册时对密码进行加密处理
     */
    public int reg(String username, String password) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
        String encodePasswod = encoder.encode(password);
        return saveToDb(username, encodePasswod);
    }

    private int saveToDb(String username, String encodePasswod) {
        return 0;
    }

}

用户将密码从前端传来之后,通过调用BCryptPasswordEncoder实例中的encode方法对密码进行加密处理,加密完成后将密文存入数据库。

 

 

参考:Spring Security入门(三):密码加密

参考:Spring Boot+Vue全栈开发实战 - 10.1.8 密码加密

 

posted @ 2020-04-07 11:34  草木物语  阅读(5052)  评论(0编辑  收藏  举报