源碼分析Shiro框架的密碼加密及校驗

前言

         我們知道Shiro框架有提供憑證匹配器類HashedCredentialsMatcher來實現密碼校驗的,在該類中可以自定義加密方式、加密次數、編碼規則等

//權限管理
@Bean
public SecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();	
    securityManager.setRealm(myShiroRealm(hashedCredentialsMatcher()));
    return securityManager;
}

//憑證匹配器
public HashedCredentialsMatcher hashedCredentialsMatcher() {
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    //採用SHA-512方式加密
    hashedCredentialsMatcher.setHashAlgorithmName("SHA-512");
    //設置加密次數
    hashedCredentialsMatcher.setHashIterations(1024);
    //true加密用的hex編碼,false用的base64編碼
    hashedCredentialsMatcher.setStoredCredentialsHexEncoded(false);
    return hashedCredentialsMatcher;
}

如上圖,假如我們採用SHA-512的加密方式,加密次數爲1024次,採用base64的編碼方式,來看一下是如何實現密碼校驗的

打開HashedCredentialsMatcher類的源碼

可以看到,他是通過doCredentialsMatch方法來進行判斷的,其中參數AuthenticationToken包含用戶輸入的密碼信息,AuthenticationInfo包含用戶的身份認證信息(如庫中存入的密碼、鹽值等信息)

先進入hashProvidedCredentials方法看一下他的實現

這裏先進行判斷,取到用戶設置的鹽值salt,然後調用了hashProvidedCredentials方法

發現最後是通過new SimpleHash方法,分別傳入加密方式、用戶輸入的密碼、庫中存入的鹽值、加密次數,來生成加密後的密碼

再進入getCredentials方法看一下他的實現

這裏先判斷在憑證匹配器中設置的編碼方式,由於前面setStoredCredentialsHexEncoded方法設置的false,所以這裏採用Base64的方式來進行解碼,最終返回庫中密碼進行Base64解碼後的值,所以我們庫中存入的密碼是加密後再進行Base64編碼後的值

模擬Shiro框架的密碼校驗

import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Controller;
 
@Controller
public class EncodePassTest {
	
    public static void main(String[] args) throws Exception {
    	String password = "123456";//原密碼
    	String hashAlgorithmName = "SHA-512";//加密方式
        int hashIterations = 1024; //加密次數
    	//生成隨機鹽值
    	String salt = new SecureRandomNumberGenerator().nextBytes().toBase64();
    	//密碼和鹽值加密並轉爲Base64
    	String dbPassord = new SimpleHash(hashAlgorithmName, password, salt, hashIterations).toBase64();
    	System.out.println("加密後需入庫的密碼:"+dbPassord);
    	/*校驗密碼*/
    	//庫中的密碼Base64解密後,對應shiro的getCredentials方法
    	SimpleHash dbPassordDecode = new SimpleHash(hashAlgorithmName);
    	dbPassordDecode.setBytes(Base64.decode(dbPassord));
    	System.out.println("庫中的密碼Base64解密後:"+dbPassordDecode);
    	//用戶輸入的密碼加密後,對應shiro的hashProvidedCredentials方法
        SimpleHash tokenHashedCredentials = new SimpleHash(hashAlgorithmName, password, salt, hashIterations);
        System.out.println("用戶輸入的密碼加密後:"+tokenHashedCredentials);
    }
    
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章