Java實現(xiàn)加鹽加密算法的示例詳解
為什么需要加密
從下面的圖片中,可以看到用戶的密碼在數(shù)據(jù)庫中存儲時,如果不對密碼加密,則是以明文的方式存儲的,如果被別人獲取到數(shù)據(jù)庫的信息,那將會將用戶的密碼泄露,從而造成安全隱患

我們可以使用MD5加密方式對用戶的密碼進行加密存儲,但是傳統(tǒng)的MD5有規(guī)則可循,可以破解
String s = "12345"; String mds1 = DigestUtils.md5DigestAsHex(s.getBytes()).toString(); System.out.println(mds1); String mds2 = DigestUtils.md5DigestAsHex(s.getBytes()).toString(); System.out.println(mds2);

我們從上述代碼及打印結果看,使用MD5對同一個字符串加密,加密后的結果不變,MD5加密是單向不可逆(不能從密文獲取明文),此時呢針對MD5這種加密方式可以使用暴力破解的方式進行破解
加鹽加密
加鹽加密算法(Salt Encryption)是一種對稱密鑰加密算法,它使用一個隨機生成的鹽(salt)作為加密和解密的關鍵參數(shù),在加密過程中,將明文和鹽作為輸入,通過哈希函數(shù)計算出一個密文和一個鹽值,在解密過程中,使用相同的鹽值和密文計算哈希值,然后再用哈希值和鹽值進行解密操作,以獲取原始的明文
MD5+鹽值加密
加密:我們可以使用一個隨機字符串(鹽值)和明文密碼組合起來,作為帶鹽值的明文密碼,再使用MD5對帶鹽值的密碼進行加密
解密:解密其實就是判斷用戶需要校驗密碼的正確性
此時需要用到加密使用的鹽值,這個鹽值如何獲取呢?
我們在數(shù)據(jù)庫存儲密碼時存儲鹽值+密文,使用一個特定的分割符將鹽值和密文分隔開,我們從數(shù)據(jù)庫獲取到密碼的密文后,也使用同樣的規(guī)則獲取到鹽值,使用該鹽值和校驗的密碼重新使用MD5生成密文,判斷新生成的密文和數(shù)據(jù)庫保存的密文是否一致,如果是一致說明密碼正確,否則密碼錯誤
加密解密的代碼實現(xiàn):
public class PasswordTools {
/**
*加鹽加密
* @param password
* @return 加密后的密碼
*/
public static String encrypt(String password){
//生成鹽值,使用隨機字符串UUID,UUID為32位的
String salt = UUID.randomUUID().toString().replace("-","");
//(鹽值+密碼)進行MD5加密,DigestUtils.md5DigestAsHex參數(shù)為字節(jié)數(shù)組,生成一個十六進制32位的字符串
String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
//將鹽值和加密的密碼組合返回,最終存儲到數(shù)據(jù)庫中的密碼
String dbPassword = salt + "$" + finalPassword;
return dbPassword;
}
/**
* 校驗密碼
* @param password
* @param dbPassword
* @return
*/
public static boolean decrypt(String password,String dbPassword){
if(StringUtils.hasLength(password) && StringUtils.hasLength(dbPassword)
&& dbPassword.length()==65 && dbPassword.contains("$")){
String[] arr = dbPassword.split("\\$");
String salt = arr[0];
//根據(jù)獲取的鹽值生成校驗的密碼
String checkPassword = salt + "$" + DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8));
//用校驗密碼與數(shù)據(jù)庫保存的密碼進行校驗
if(checkPassword.equals(dbPassword)){
return true;
}
}
return false;
}
public static void main(String[] args) {
String dbPassword = encrypt("12345");
System.out.println(decrypt("12345",dbPassword)); //true
System.out.println(decrypt("45678",dbPassword)); //false
}
}

Spring Security加鹽
1.添加Spring Security依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2.關閉Spring Security的認證
在啟動類上的注解添加排除,禁止Spring boot啟動時自動加載Spring Security框架
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}3.使用BCryptPasswordEncoder對象提供的encode(String password)加密,和matches(String password,String dbPassword)解密方法
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = "123456";
System.out.println(passwordEncoder.encode(password));
System.out.println(passwordEncoder.encode(password));
System.out.println(passwordEncoder.encode(password));
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = "123456";
String dbPassword = passwordEncoder.encode(password);
boolean result1 = passwordEncoder.matches(password,dbPassword); //正確的密碼
boolean result2 = passwordEncoder.matches("12345",dbPassword); //錯誤的密碼
System.out.println(result1);
System.out.println(result2);
到此這篇關于Java實現(xiàn)加鹽加密算法的示例詳解的文章就介紹到這了,更多相關Java加鹽加密算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java 實戰(zhàn)項目錘煉之樸素風格個人博客系統(tǒng)的實現(xiàn)流程
讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java+vue+Springboot+ssm+mysql+maven+redis實現(xiàn)一個樸素風格的個人博客系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11
使用springboot整合websocket實現(xiàn)群聊教程
websocket怎么說呢,就是服務器可以主動向客戶端發(fā)起對話,下面就是springboot整合websocket實現(xiàn)群聊的操作代碼,一起來看一下get新技能吧2021-08-08
Spring Boot應用與Prometheus和Grafana整合方案
通過將Spring Boot應用與Prometheus和Grafana進行整合,我們可以實現(xiàn)對Spring Boot應用的全面監(jiān)控和可視化展示,本文將詳細介紹如何將Spring Boot應用與Prometheus和Grafana進行整合,實現(xiàn)對Spring Boot應用的全面監(jiān)控,感興趣的朋友一起看看吧2025-11-11
Spring Boot實現(xiàn)異步請求(Servlet 3.0)
在spring 3.2 及以后版本中增加了對請求的異步處理,這篇文章主要介紹了Spring Boot實現(xiàn)異步請求(Servlet 3.0),感興趣的小伙伴們可以參考一下。2017-04-04
springboot發(fā)送request請求的方式小結
在Java中,發(fā)送HTTP請求是常見需求,hutool工具包和RestTemplate類是實現(xiàn)此功能的兩種主流方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-09-09

