天天看點

Spring security中的BCryptPasswordEncoder方法對密碼進行加密與密碼比對

淺談使用springsecurity中的BCryptPasswordEncoder方法對密碼進行加密(encode)與密碼比對(matches)

spring security中的BCryptPasswordEncoder方法采用SHA-256 +随機鹽+密鑰對密碼進行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(這個與編碼/解碼一樣),但是采用Hash處理,其過程是不可逆的。

(1)加密(encode):注冊使用者時,使用SHA-256+随機鹽+密鑰把使用者輸入的密碼進行hash處理,得到密碼的hash值,然後将其存入資料庫中。

(2)密碼比對(matches):使用者登入時,密碼比對階段并沒有進行密碼解密(因為密碼經過Hash處理,是不可逆的),而是使用相同的算法把使用者輸入的密碼進行hash處理,得到密碼的hash值,然後将其與從資料庫中查詢到的密碼hash值進行比較。如果兩者相同,說明使用者輸入的密碼正确。

這正是為什麼處理密碼時要用hash算法,而不用加密算法。因為這樣處理即使資料庫洩漏,黑客也很難破解密碼(破解密碼隻能用彩虹表)。

學習到這一塊,檢視了一些源碼。以BCryptPasswordEncoder為例

public class BCryptPasswordEncoderTest {
    public static void main(String[] args) {
        String pass = "admin";
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
        String hashPass = bcryptPasswordEncoder.encode(pass);
        System.out.println(hashPass);

        boolean f = bcryptPasswordEncoder.matches("admin",hashPass);
        System.out.println(f);

    }
}      

可以看到,每次輸出的hashPass 都不一樣,但是最終的f都為 true,即比對成功。檢視代碼,可以看到,其實每次的随機鹽,都儲存在hashPass中。在進行matchs進行比較時,調用BCrypt 的String hashpw(String password, String salt)方法。兩個參數即”admin“和 hashPass

如果隻是想使用SpringSecurity + SpringBoot完成密碼加密/解密操作,而不使用SpringSecurty提供的其它權證驗證功能。具體步驟如下:

1 BCrypt密碼加密

1.1 準備工作

任何應用考慮到安全,絕不能明文的方式儲存密碼。密碼應該通過雜湊演算法進行加密。

有很多标準的算法比如SHA或者MD5,結合salt(鹽)是一個不錯的選擇。 Spring Security

提供了BCryptPasswordEncoder類,實作Spring的PasswordEncoder接口使用BCrypt強

哈希方法來加密密碼。

BCrypt強哈希方法 每次加密的結果都不一樣。

(1)tensquare_user工程的pom引入依賴

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

(2)添加配置類 (資源/工具類中提供)

我們在添加了spring security依賴後,所有的位址都被spring security所控制了,我們目

前隻是需要用到BCrypt密碼加密的部分,是以我們要添加一個配置類,配置為所有位址

都可以匿名通路

/**
* 安全配置類
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
      .antMatchers("/**").permitAll()
      .anyRequest().authenticated()
      .and().csrf().disable();
  }
}      

3)修改tensquare_user工程的Application, 配置bean

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

 之後就可以使用BCryptPasswordEncoder中的方法完成加密/解密操作:

加密:
bcryptPasswordEncoder.encoder(password)
解密:
bcrytPasswordEncoder.matches(rawPassword,encodedPassword)