Java實(shí)現(xiàn)加鹽加密算法的示例詳解
為什么需要加密
從下面的圖片中,可以看到用戶的密碼在數(shù)據(jù)庫(kù)中存儲(chǔ)時(shí),如果不對(duì)密碼加密,則是以明文的方式存儲(chǔ)的,如果被別人獲取到數(shù)據(jù)庫(kù)的信息,那將會(huì)將用戶的密碼泄露,從而造成安全隱患
我們可以使用MD5加密方式對(duì)用戶的密碼進(jìn)行加密存儲(chǔ),但是傳統(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);
我們從上述代碼及打印結(jié)果看,使用MD5對(duì)同一個(gè)字符串加密,加密后的結(jié)果不變,MD5加密是單向不可逆(不能從密文獲取明文),此時(shí)呢針對(duì)MD5這種加密方式可以使用暴力破解的方式進(jìn)行破解
加鹽加密
加鹽加密算法(Salt Encryption)是一種對(duì)稱密鑰加密算法,它使用一個(gè)隨機(jī)生成的鹽(salt)作為加密和解密的關(guān)鍵參數(shù),在加密過(guò)程中,將明文和鹽作為輸入,通過(guò)哈希函數(shù)計(jì)算出一個(gè)密文和一個(gè)鹽值,在解密過(guò)程中,使用相同的鹽值和密文計(jì)算哈希值,然后再用哈希值和鹽值進(jìn)行解密操作,以獲取原始的明文
MD5+鹽值加密
加密:我們可以使用一個(gè)隨機(jī)字符串(鹽值)和明文密碼組合起來(lái),作為帶鹽值的明文密碼,再使用MD5對(duì)帶鹽值的密碼進(jìn)行加密
解密:解密其實(shí)就是判斷用戶需要校驗(yàn)密碼的正確性
此時(shí)需要用到加密使用的鹽值,這個(gè)鹽值如何獲取呢?
我們?cè)跀?shù)據(jù)庫(kù)存儲(chǔ)密碼時(shí)存儲(chǔ)鹽值+密文,使用一個(gè)特定的分割符將鹽值和密文分隔開(kāi),我們從數(shù)據(jù)庫(kù)獲取到密碼的密文后,也使用同樣的規(guī)則獲取到鹽值,使用該鹽值和校驗(yàn)的密碼重新使用MD5生成密文,判斷新生成的密文和數(shù)據(jù)庫(kù)保存的密文是否一致,如果是一致說(shuō)明密碼正確,否則密碼錯(cuò)誤
加密解密的代碼實(shí)現(xiàn):
public class PasswordTools { /** *加鹽加密 * @param password * @return 加密后的密碼 */ public static String encrypt(String password){ //生成鹽值,使用隨機(jī)字符串UUID,UUID為32位的 String salt = UUID.randomUUID().toString().replace("-",""); //(鹽值+密碼)進(jìn)行MD5加密,DigestUtils.md5DigestAsHex參數(shù)為字節(jié)數(shù)組,生成一個(gè)十六進(jìn)制32位的字符串 String finalPassword = DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8)); //將鹽值和加密的密碼組合返回,最終存儲(chǔ)到數(shù)據(jù)庫(kù)中的密碼 String dbPassword = salt + "$" + finalPassword; return dbPassword; } /** * 校驗(yàn)密碼 * @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ù)獲取的鹽值生成校驗(yàn)的密碼 String checkPassword = salt + "$" + DigestUtils.md5DigestAsHex((salt+password).getBytes(StandardCharsets.UTF_8)); //用校驗(yàn)密碼與數(shù)據(jù)庫(kù)保存的密碼進(jìn)行校驗(yàn) 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.關(guān)閉Spring Security的認(rèn)證
在啟動(dòng)類上的注解添加排除,禁止Spring boot啟動(dòng)時(shí)自動(dòng)加載Spring Security框架
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
3.使用BCryptPasswordEncoder
對(duì)象提供的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); //錯(cuò)誤的密碼 System.out.println(result1); System.out.println(result2);
到此這篇關(guān)于Java實(shí)現(xiàn)加鹽加密算法的示例詳解的文章就介紹到這了,更多相關(guān)Java加鹽加密算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Web使用POI導(dǎo)出Excel的方法詳解
這篇文章主要介紹了Java Web使用POI導(dǎo)出Excel的方法,結(jié)合實(shí)例形式詳細(xì)分析了Java Web使用POI導(dǎo)出Excel的具體操作步驟、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-06-06詳解Idea SpringBoot搭建SpringCloud的準(zhǔn)備工作(推薦)
這篇文章主要介紹了Idea SpringBoot搭建SpringCloud的準(zhǔn)備工作(推薦),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10java WebSocket實(shí)現(xiàn)聊天消息推送功能
這篇文章主要為大家詳細(xì)介紹了java WebSocket實(shí)現(xiàn)聊天消息推送功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Java用list儲(chǔ)存,遍歷,查詢指定信息過(guò)程詳解
這篇文章主要介紹了Java用list儲(chǔ)存,遍歷,查詢指定信息過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Java對(duì)象和JSON字符串之間的轉(zhuǎn)換方法(全網(wǎng)最清晰)
這篇文章主要介紹了如何在Java中使用Jackson庫(kù)將對(duì)象轉(zhuǎn)換為JSON字符串,并提供了一個(gè)簡(jiǎn)單的工具類示例,該工具類支持基本的轉(zhuǎn)換功能,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2025-02-02