欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Security加密和匹配及原理解析

 更新時間:2023年10月25日 09:28:15   作者:oh LAN  
我們開發(fā)時進行密碼加密,可用的加密手段有很多,比如對稱加密、非對稱加密、信息摘要等,本篇文章給大家介紹Spring Security加密和匹配及原理解析,感興趣的朋友一起看看吧

一. 密碼加密簡介

1. 散列加密概述

我們開發(fā)時進行密碼加密,可用的加密手段有很多,比如對稱加密、非對稱加密、信息摘要等。在一般的項目里,常用的就是信息摘要算法,也可以被稱為散列加密函數(shù),或者稱為散列算法、哈希函數(shù)。這是一種可以從任何數(shù)據(jù)中創(chuàng)建數(shù)字“指紋”的方法,常用的散列函數(shù)有 MD5 消息摘要算法、安全散列算法(Secure Hash Algorithm)等。

2. 散列加密原理

散列函數(shù)通過把消息或數(shù)據(jù)壓縮成摘要信息,使得數(shù)據(jù)量變小,將數(shù)據(jù)的格式固定下來,然后將數(shù)據(jù)打亂混合,再重新創(chuàng)建成一個散列值,從而達到加密的目的。散列值通常用一個短的隨機字母和數(shù)字組成的字符串來代表,一個好的散列函數(shù)在輸入域中很少出現(xiàn)散列沖突。在散列表和數(shù)據(jù)處理時,如果我們不抑制沖突來區(qū)別數(shù)據(jù),會使得數(shù)據(jù)庫中的記錄很難找到。

但是僅僅使用散列函數(shù)還不夠,如果我們只是單純的使用散列函數(shù)而不做特殊處理,其實是有風(fēng)險的!比如在兩個用戶密碼明文相同時,生成的密文也會相同,這樣就增加了密碼泄漏的風(fēng)險。

所以為了增加密碼的安全性,一般在密碼加密過程中還需要“加鹽”,而所謂的“鹽”可以是一個隨機數(shù),也可以是用戶名。”加鹽“之后,即使密碼的明文相同,用戶生成的密碼密文也不相同,這就可以極大的提高密碼的安全性。

傳統(tǒng)的加鹽方式需要在數(shù)據(jù)庫中利用專門的字段來記錄鹽值,這個字段可以是用戶名字段(因為用戶名唯一),也可以是一個專門記錄鹽值的字段,但這樣的配置比較繁瑣。

二、SpringSecurity 中的密碼源碼分析

當(dāng)我們項目只引入springsecurity依賴之后,接下來什么事情都不用做,我們直接來啟動項目。

在項目啟動過程中,我們會看到如下一行日志:

Using generated security password: 10abfb2j-36e1-446a-jh9b-f70024fc89ab

這就是 Spring Security 為默認用戶 user 生成的臨時密碼,是一個 UUID 字符串。這個密碼和用戶相關(guān)的自動化配置類在 UserDetailsServiceAutoConfiguration 里邊,在該類的 getOrDeducePassword 方法中,我們看到如下一行日志: 

if (user.isPasswordGenerated()) {
	logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));
}

毫無疑問,我們在控制臺看到的日志就是從這里打印出來的。打印的條件是 isPasswordGenerated 方法返回 true,即密碼是默認生成的。

進而我們發(fā)現(xiàn),user.getPassword 出現(xiàn)在 SecurityProperties 中,在 SecurityProperties 中我們看到如下定義:

/**
 * Default user name.
 */
private String name = "user";
/**
 * Password for the default user name.
 */
private String password = UUID.randomUUID().toString();
private boolean passwordGenerated = true;

 可以看到,默認的用戶名就是 user,默認的密碼則是 UUID,而默認情況下,passwordGenerated 也為 true。

SecurityProperties默認的用戶就定義在它里邊,是一個靜態(tài)內(nèi)部類,我們?nèi)绻x自己的用戶名密碼,必然是要去覆蓋默認配置,我們先來看下 SecurityProperties 的定義:

@ConfigurationProperties(prefix = "spring.security")
publicclass SecurityProperties {}

這就很清晰了,我們只需要以 spring.security.user 為前綴,去定義用戶名密碼即可:

spring.security.user.name=admin
spring.security.user.password=123456

這就是我們新定義的用戶名密碼。

在 properties 中定義的用戶名密碼最終是通過 set 方法注入到屬性中去的,這里我們順便來看下 SecurityProperties.User#setPassword 方法:

public void setPassword(String password) {
	if (!StringUtils.hasLength(password)) {
		return;
	}
	this.passwordGenerated = false;
	this.password = password;
}

從這里我們可以看到,application.properties 中定義的密碼在注入進來之后,還順便設(shè)置了 passwordGenerated 屬性為 false,這個屬性設(shè)置為 false 之后,控制臺就不會打印默認的密碼了。

此時重啟項目,就可以使用自己定義的用戶名/密碼登錄了

除了上面的配置文件這種方式之外,我們也可以在配置類中配置用戶名/密碼。

@Configuration
publicclass SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("123456").roles("admin");
    }
}

在配置類中配置,我們就要指定 PasswordEncoder 了,這是一個非常關(guān)鍵的東西

三、PasswordEncoder

1、PasswordEncoder

security中用于加密的接口就是PasswordEncoder,接口用于執(zhí)行密碼的單向轉(zhuǎn)換,以便安全地存儲密碼,源碼如下

public interface PasswordEncoder {
//該方法提供了明文密碼的加密處理,加密后密文的格式主要取決于PasswordEncoder接口實現(xiàn)類實例。
    String encode(CharSequence rawPassword);
//匹配存儲的密碼以及登錄時傳遞的密碼(登錄密碼是經(jīng)過加密處理后的字符串)是否匹配,如果匹配該方法則會返回true,第一個參數(shù)表示需要被解析的密碼 第二個參數(shù)表示存儲的密碼
    boolean matches(CharSequence rawPassword, String encodedPassword);
 
    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

PasswordEncoder 中的 encode 方法是我們在用戶注冊的時候手動調(diào)用,而matches 方法,則是由系統(tǒng)調(diào)用,默認是在 DaoAuthenticationProvider#additionalAuthenticationChecks 方法中調(diào)用的。

protected void additionalAuthenticationChecks(UserDetails userDetails,
  UsernamePasswordAuthenticationToken authentication)
  throws AuthenticationException {
 if (authentication.getCredentials() == null) {
  logger.debug("Authentication failed: no credentials provided");
  throw new BadCredentialsException(messages.getMessage(
    "AbstractUserDetailsAuthenticationProvider.badCredentials",
    "Bad credentials"));
 }
 String presentedPassword = authentication.getCredentials().toString();
 if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
  logger.debug("Authentication failed: password does not match stored value");
  throw new BadCredentialsException(messages.getMessage(
    "AbstractUserDetailsAuthenticationProvider.badCredentials",
    "Bad credentials"));
 }
}

 可以看到,密碼比對就是通過 passwordEncoder.matches 方法來進行的。

Spring Security 提供了多種密碼加密方案,官方推薦使用 BCryptPasswordEncoder,BCryptPasswordEncoder 使用 BCrypt 強哈希函數(shù),開發(fā)者在使用時可以選擇提供 strength 和 SecureRandom 實例。strength 越大,密鑰的迭代次數(shù)越多,密鑰迭代次數(shù)為 2^strength。strength 取值在 4~31 之間,默認為 10。

不同于 Shiro 中需要自己處理密碼加鹽,在 Spring Security 中,BCryptPasswordEncoder 就自帶了鹽,處理起來非常方便。而 BCryptPasswordEncoder 就是 PasswordEncoder 接口的實現(xiàn)類。其他實現(xiàn)類列表如下

舉例使用

三、hutool 工具 BCrypt 進行加密和匹配

( cn.hutool.crypto.digest.BCrypt )

import cn.hutool.crypto.digest.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
public class UmsMemberController {
    public static void main(String[] args) {
        String pas="123456";
        String pas1="$2a$10$mMslOUUCblGnotpq5G3j2er8OuqsIU08YF.x50//YOB6vLrGNd7Wq";
        BCryptPasswordEncoder n=new BCryptPasswordEncoder();
        System.out.println("加密前密碼:"+pas);
        System.out.println("加密后密碼:"+pas1);
        System.out.println("重新進行加密后密碼:"+n.encode(pas));
        if (n.matches(pas,pas1)){
            System.out.println("True - 匹配:"+"11111111111111111111111");
        }else {
            System.out.println("False - 未匹配:"+"2222222222222222222222");
        }
        System.out.println("======================= 兩種方法類似都可進行加密和匹配 =======================");
        if (BCrypt.checkpw(pas,pas1)){
            System.out.println("True - 匹配:"+"11111111111111111111111");
        }else {
            System.out.println("False - 未匹配:"+"2222222222222222222222");
        }
    }
}

到此這篇關(guān)于Spring Security加密和匹配的文章就介紹到這了,更多相關(guān)Spring Security加密和匹配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • j2ee之AJAX二級聯(lián)動效果

    j2ee之AJAX二級聯(lián)動效果

    這篇文章主要為大家詳細介紹了j2ee之AJAX二級聯(lián)動效果的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • RestTemplate報錯I/O?error?on?POST?request?for的解決辦法

    RestTemplate報錯I/O?error?on?POST?request?for的解決辦法

    這篇文章主要給大家介紹了關(guān)于RestTemplate報錯I/O?error?on?POST?request?for的解決辦法,文中通過代碼實例將解決的辦法介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • 史上最難的一道Java面試題

    史上最難的一道Java面試題

    本文給大家分享一道史上最難的一道Java面試題,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-03-03
  • java實現(xiàn)批量導(dǎo)入Excel表格數(shù)據(jù)到數(shù)據(jù)庫

    java實現(xiàn)批量導(dǎo)入Excel表格數(shù)據(jù)到數(shù)據(jù)庫

    這篇文章主要為大家詳細介紹了java實現(xiàn)批量導(dǎo)入Excel表格數(shù)據(jù)到數(shù)據(jù)庫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • maven依賴的配置和排除依賴過程

    maven依賴的配置和排除依賴過程

    這篇文章主要介紹了maven依賴的配置和排除依賴過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • java連接HBase,連接不上報錯can not resolve問題及解決

    java連接HBase,連接不上報錯can not resolve問題及解決

    這篇文章主要介紹了java連接HBase,連接不上報錯can not resolve問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java必會的Synchronized底層原理剖析

    Java必會的Synchronized底層原理剖析

    synchronized作為Java程序員最常用同步工具,很多人卻對它的用法和實現(xiàn)原理一知半解,以至于還有不少人認為synchronized是重量級鎖,性能較差,盡量少用。但不可否認的是synchronized依然是并發(fā)首選工具,本文就來詳細講講
    2022-10-10
  • Spring Cloud Gateway替代zuul作為API網(wǎng)關(guān)的方法

    Spring Cloud Gateway替代zuul作為API網(wǎng)關(guān)的方法

    本文簡要介紹如何使用Spring Cloud Gateway 作為API 網(wǎng)關(guān)(不是使用zuul作為網(wǎng)關(guān)),結(jié)合實例代碼給大家詳細講解,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • SpringCloud中的灰度路由使用詳解

    SpringCloud中的灰度路由使用詳解

    這篇文章主要介紹了SpringCloud中的灰度路由使用詳解,在微服務(wù)中,?通常為了高可用,?同一個服務(wù)往往采用集群方式部署,?即同時存在幾個相同的服務(wù),而灰度的核心就?是路由,?通過我們特定的策略去調(diào)用目標(biāo)服務(wù)線路,需要的朋友可以參考下
    2023-08-08
  • Java 高并發(fā)九:鎖的優(yōu)化和注意事項詳解

    Java 高并發(fā)九:鎖的優(yōu)化和注意事項詳解

    本文主要介紹Java高并發(fā)鎖的優(yōu)化和注意事項,這里整理了詳細的資料,并講解了 1. 鎖優(yōu)化的思路和方法 2. 虛擬機內(nèi)的鎖優(yōu)化 3. 一個錯誤使用鎖的案例 4. ThreadLocal及其源碼分析等知識,有需要的小伙伴可以參考下
    2016-09-09

最新評論