# BCryptPasswordEncoder **Repository Path**: wl8888/bcrypt-password-encoder ## Basic Information - **Project Name**: BCryptPasswordEncoder - **Description**: BCryptPasswordEncoder的使用及原理 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2023-03-01 - **Last Updated**: 2024-05-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 一 介绍 spring security中的BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。 (不可逆加密SHA: 基本原理:加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,无法根据密文推算出明文。 RSA算法历史:底层-欧拉函数) 1)加密(encode):注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。 2)密码匹配(matches):用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的),而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。如果两者相同,说明用户输入的密码正确。 ## 二 案例使用 ### 2.1 添加依赖 ```xml org.springframework.security spring-security-core 5.7.6 ``` ## 2.2 PasswordConfig 为了防止有人能根据密文推测出salt,我们需要在使用BCryptPasswordEncoder时配置随即密钥,创建一个PasswordConfig配置类,注册BCryptPasswordEncoder对象: ```java import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import java.security.SecureRandom; @Data @Configuration @ConfigurationProperties(prefix = "encoder.crypt") public class PasswordConfig { /** * 加密强度 */ private int strength; /** * 干扰因子 */ private String secret; @Bean public BCryptPasswordEncoder passwordEncoder() { //System.out.println("secret = " + secret); //对干扰因子加密 SecureRandom secureRandom = new SecureRandom(secret.getBytes()); //对密码加密 return new BCryptPasswordEncoder(strength, secureRandom); } } ``` ### 2.3 application.yml ```yml encoder: crypt: secret: ${random.uuid} # 随机的密钥,使用uuid strength: 6 # 加密强度4~31,决定盐加密时的运算强度,超过10以后加密耗时会显著增加 ``` ### 2.4 单元测试 ```java import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @SpringBootTest class ApplicationTests { final static private String password = "123456"; @Autowired private BCryptPasswordEncoder encoder; @Test void savePassword() { // encode():对明文字符串进行加密 //注册用户时,使用SHA-256+随机盐+密钥把用户输入的密码进行hash处理,得到密码的hash值,然后将其存入数据库中。 String encode1 = encoder.encode(password); System.out.println("encode1:" + encode1); String encode2 = encoder.encode(password); System.out.println("encode2:" + encode2); // matches():对加密前和加密后是否匹配进行验证 //用户登录时,密码匹配阶段并没有进行密码解密(因为密码经过Hash处理,是不可逆的), // 而是使用相同的算法把用户输入的密码进行hash处理,得到密码的hash值,然后将其与从数据库中查询到的密码hash值进行比较。 // 如果两者相同,说明用户输入的密码正确。 boolean matches1 = encoder.matches(password, encode1); System.out.println("matches1:" + matches1); boolean matches2 = encoder.matches(password, encode2); System.out.println("matches2:" + matches2); } } ``` ### 2.5 结果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/fad39f6e2f2d4cadb02e052d66cfa936.png) [SpringSecurity中的BCryptPasswordEncoder算法](https://blog.csdn.net/weixin_43453386/article/details/123716830) [SpringSecurity中的密码加密算法:BCryptPasswordEncoder](https://blog.csdn.net/u012888704/article/details/107406374) [BCryptPasswordEncoder使用](https://cloud.tencent.com/developer/article/1779217)