美文网首页
spring security中的密码加密:BCrypt算法工具

spring security中的密码加密:BCrypt算法工具

作者: chushiyan | 来源:发表于2019-12-30 21:17 被阅读0次

    spring security中的密码加密:BCrypt算法工具类BCryptPasswordEncoder

      spring security中有多种密码加密方式,MD5算法的Md5PasswordEncoder、SHA 算法的ShaPasswordEncoder,但由于是弱加密算法,都被弃用了。推荐使用的是BCrypt算法的BCryptPasswordEncoder。

    一、BCryptPasswordEncoder的使用

    (一)添加依赖

      在SpringBoot项目中加入spring security依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    

    (二)放行请求

      添加了spring security依赖后,所有的请求都被spring security所控制了,这里只是使用BCrypt密码加密的部分,所以需要编写配置类,配置为所有地址都可以匿名访问。

    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    /**
     * @author chushiyan
     * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
     * @description
     */
    
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                .and().csrf().disable();
        }
    }
    

    (三)启动类中配置bean

        @Bean
        public BCryptPasswordEncoder getBcryptPasswordEncoder(){
            return new BCryptPasswordEncoder();
        }
    
    

    (四)加密密码

    // 加密密码
    user.setPassword(bCryptPasswordEncoder.encode(password));
    
    

    (五)校验密码

    // 参数一:待检验的、未加密的密码
    // 参数二:从数据库中查询出的加密后密码
    bCryptPasswordEncoder.matches(password, userFromDB.getPassword())
    
    

    二、深入了解BCryptPasswordEncoder

    (一)测试生成密码

    /**
     * @author chushiyan
     * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
     * @description
     */
    @SpringBootTest
    class ApplicationTests {
    
        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;
    
        @Test
        public void testBCryptPasswordEncoder() {
            for (int i = 0; i < 10; i++) {
                String password = "123456";
                String hashed = bCryptPasswordEncoder.encode(password);
                System.out.println(hashed);
            }
        }
    }
    

      控制台输出:

    $2a$10$A/Jty.uPopRKNL/Pagnhvufb9sPScp74h93qHGxFztBlrzdOJU66a
    $2a$10$I4q0m0Tesq5GRLETEyXOPObHaI8JYGohK1m/63KtAKjRjHws1.Fi.
    $2a$10$ByPK1poz.JRGSlO/F9CiqexXW2VEgeaScjuQPLPqksLRGv8xtd5uy
    $2a$10$vs3Vj7BiQGRnjIWq895CXunLUyDAVRrZccJR/ggMy/nWAiklUxXJC
    $2a$10$4LKrbmr4u7q71yPq9PZLxOkCUCSo1Q.o73nfTXauIDCoKBMoFs7vG
    $2a$10$Z5VD7fjGmze05VuWMJxVIuPXXO77YIFDVUi/XYQPnb6G3t8mikPJm
    $2a$10$T39UcqdG73nfHLiqzYz.tOtTk7efiFUqmaqxew6xHL9gsBgFmpvCi
    $2a$10$9VhF9phPI6VKSpy2ne3AteBfCZUBpWEkJoEh2uaGO.yONcl.fmP.2
    $2a$10$gZv6eWEQ/TYwwHQJ1Hmex.v8XvcpzzyjIaoWjGOapYLanMMhrYBNW
    $2a$10$ZVH0p2D0xRJ2CBIaWzdF5eT.4TKpSwDM7wP/IA4Qbv8u7lzOL7ipe
    

      为什么密码都是123456,而加密后的结果不一样?因为BCryptPasswordEncoder中的encode()内部调用BCrypt类随机生成了盐(salt),加了不同的盐进行hash自然不一样。

    (二)详解加密后的密码

    $2a$10$A/Jty.uPopRKNL/Pagnhvufb9sPScp74h93qHGxFztBlrzdOJU66a
    

    加密后的密码长度为60(所以设计数据库时得保证该字段长度不小于60)

    说明
    $ 分割符
    $2a BCrypt加密算法版本,在BCryptPasswordEncoder类内部定义了一个枚举类,枚举了3个加密算法版本:
    public enum BCryptVersion {
    2A("2a"),
    2Y("2y"),
    2B("2b");
    可以通过构造函数指定版本:public BCryptPasswordEncoder(BCryptVersion version)
    如:new BCryptPasswordEncoder(BCryptPasswordEncoder.BCryptVersion.$2A);
    $10 表示10次循环加盐salt。默认10次,最少4次,最多31次。
    可以通过构造函数指定次数:public BCryptPasswordEncoder(int strength)
    10$之后的22位 盐。BCryptPasswordEncoder内部调用BCrypt的gensalt()方法随机生成
    最后的31位 明文密码password和盐hash后的值

    三、非SpringBoot项目使用BCrypt加密算法

      BCrypt是一个算法,各个语言都有自己的实现。在java中有jBCrypt,spring security中也实现了BCrypt算法(没有依赖jBCrypt)。
      如果不是SpringBoot项目,就可以使用jBCrypt。

      jBCrypt官网

      官网示例:

    // Hash a password for the first time
    String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
    
    // gensalt's log_rounds parameter determines the complexity
    // the work factor is 2**log_rounds, and the default is 10
    String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
    
    // Check that an unencrypted password matches one that has
    // previously been hashed
    if (BCrypt.checkpw(candidate, hashed))
        System.out.println("It matches");
    else
        System.out.println("It does not match");
    

    导包:

            <dependency>
                <groupId>org.mindrot</groupId>
                <artifactId>jbcrypt</artifactId>
                <version>0.4</version>
            </dependency>
    

    或者加入jbcrypt-0.4.jar(这个包其实就BCrypt.java这一个类)

    相关文章

      网友评论

          本文标题:spring security中的密码加密:BCrypt算法工具

          本文链接:https://www.haomeiwen.com/subject/hdcvoctx.html