Java實(shí)現(xiàn)MD5加密算法方法例子
1. MD5 加密算法
1.1 MD5 算法介紹
MD5 消息摘要算法,英文:MD5 Message-Digest Algorithm ,一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個(gè)128位(16字節(jié))的散列值(hash value),用于確保信息傳輸完整一致。
MD5 是單向加密不可逆的,也就是常說(shuō)的非對(duì)稱(chēng)加密,常用于用戶密碼的加密,這樣即使密碼泄露也不知道對(duì)應(yīng)的明文信息,有效的保護(hù)系統(tǒng)和用戶的隱私信息。
MD5 算法產(chǎn)生的是一個(gè) 128 位的散列值,128 位是指的二進(jìn)制中的 128 位,具體占 16 字節(jié)(每個(gè)字節(jié)可以表示為 8 位二進(jìn)制數(shù))。
MD5 加密最終會(huì)將 128 位數(shù)字轉(zhuǎn)換成十六進(jìn)制表示,每個(gè)字節(jié)( 8 位)轉(zhuǎn)成 2 位十六進(jìn)制數(shù),最終得到 32 個(gè)字符,其中每?jī)蓚€(gè)字符代表一個(gè)十六進(jìn)制數(shù),因此最終 MD5 加密結(jié)果字符長(zhǎng)度為 32 位。
1.2 算法加鹽
由于 MD5 算法是單向的,不能被反向解析,但是可以通過(guò)正向加密后的字典表(Lookup 表和 Rainbow 表)對(duì)比的方式進(jìn)行暴力破解。
對(duì)于此種情況可以使用自定義偏移常量(鹽值)的方法來(lái)降低加密結(jié)果被破解的可能。
2. Java 中實(shí)現(xiàn) MD5 加密
2.1 JDK 提供的 MD5 算法
Java 中進(jìn)行 MD5 加密使用的是 JDk 中的 java.security
包中的 MessageDigest 類(lèi),其中的 getInstance() 方法可以根據(jù)算法名稱(chēng)獲取對(duì)應(yīng)的算法實(shí)例。
// 獲取 MD5 算法實(shí)例對(duì)象 MessageDigest md = MessageDigest.getInstance("MD5");
2.2 字符串的 MD5 加密
根據(jù) JDK 提供的算法,可以對(duì)任意的字符內(nèi)容進(jìn)行 MD5 加密處理,加密處理的流程為:
獲取 MD5 算法實(shí)例
獲取需要加密的字符內(nèi)容對(duì)應(yīng)的的字節(jié)信息,可指定編碼方式
對(duì)得到的字節(jié)信息使用 MD5 算法處理,得到加密后的字節(jié)
將加密后的字節(jié)轉(zhuǎn)化為 16 進(jìn)制字符串
返回加密后的字符串信息
public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] md5 = md.digest(data.getBytes(StandardCharsets.UTF_8)); // 將處理后的字節(jié)轉(zhuǎn)成 16 進(jìn)制,得到最終 32 個(gè)字符 StringBuilder sb = new StringBuilder(); for (byte b : md5) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
MessageDigest 類(lèi)可以獲取 MD5 實(shí)例
md.digest() 計(jì)算字符串內(nèi)容的摘要,并得到計(jì)算后的 hash value
StandardCharsets.UTF_8 用來(lái)指定計(jì)算時(shí)使用的編碼格式,如果不指定則會(huì)使用系統(tǒng)默認(rèn)編碼格式,系統(tǒng)之間不統(tǒng)一會(huì)造成中文亂碼
sb.append(String.format(“%02x”, b)) 用于將字節(jié)信息轉(zhuǎn)為十六進(jìn)制
最后,可以在 main 方法中驗(yàn)證 MD5 算法的有效性
public static void main(String[] args) { String password = "testPsd"; String passwordMd5Str = md5(password); System.out.println("加密前: " + password); System.out.println("加密后: " + passwordMd5Str); }
輸出結(jié)果為
加密前: testPsd
加密后: 52c165118aae94580335f628dc8b202b
2.3 加鹽處理
使用鹽值可以進(jìn)一步提升 MD5 加密算法安全性,降低破解風(fēng)險(xiǎn)。
public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); // 加鹽處理,需要將對(duì)應(yīng)的鹽記錄,用于驗(yàn)證密碼 int randomNum = new SecureRandom().nextInt(1000); byte[] md5 = md.digest((data + randomNum).getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : md5) { //sb.append(Integer.toHexString(b & 0xff)); // 字符串格式轉(zhuǎn)成 16 進(jìn)制 sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
2.4 文件的 MD5 值計(jì)算
MD5 算法除了用于對(duì)字符內(nèi)容進(jìn)行加密,還可以用來(lái)對(duì)文件進(jìn)行 MD5 校驗(yàn)。
文件進(jìn)行 MD5 校驗(yàn)即針對(duì)每個(gè)文件可以計(jì)算出一個(gè) MD5 值來(lái)作為該文件的唯一編碼,如果文件在傳輸過(guò)程中發(fā)生了修改,那么最終得到文件的 MD5 值會(huì)發(fā)生變化。
根據(jù)上述 MD5 校驗(yàn)方法可以驗(yàn)證文件的有效性,保證文件在傳輸過(guò)程中不會(huì)被篡改。
public static String md5ForFile(String filePath) { MessageDigest md = null; byte[] fileBytes = new byte[0]; try { md = MessageDigest.getInstance("MD5"); fileBytes = Files.readAllBytes(Paths.get(filePath)); }catch (NoSuchAlgorithmException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } byte[] md5 = md.digest(fileBytes); StringBuilder sb = new StringBuilder(); for (byte b : md5) { sb.append(String.format("%02x", b)); } return sb.toString(); }
在 main 方法中驗(yàn)證 MD5 算法的有效性
public static void main(String[] args) { String filePath = "C:\桌面\test.jpg"; String fileMd5Str = md5ForFile(filePath); System.out.println("加密后: " + fileMd5Str); }
輸出結(jié)果為
加密后: 75f590a718ee6e8f65c0e7bf780a9e79
附:MD5用途
1.防止被篡改:
1)比如發(fā)送一個(gè)電子文檔,發(fā)送前,我先得到MD5的輸出結(jié)果a。然后在對(duì)方收到電子文檔后,對(duì)方也得到一個(gè)MD5的輸出結(jié)果b。如果a與b一樣就代表中途未被篡改。
2)比如我提供文件下載,為了防止不法分子在安裝程序中添加木馬,我可以在網(wǎng)站上公布由安裝文件得到的MD5輸出結(jié)果。
3)SVN在檢測(cè)文件是否在CheckOut后被修改過(guò),也是用到了MD5.
2.防止直接看到明文:
現(xiàn)在很多網(wǎng)站在數(shù)據(jù)庫(kù)存儲(chǔ)用戶的密碼的時(shí)候都是存儲(chǔ)用戶密碼的MD5值。這樣就算不法分子得到數(shù)據(jù)庫(kù)的用戶密碼的MD5值,也無(wú)法知道用戶的密碼。(比如在UNIX系統(tǒng)中用戶的密碼就是以MD5(或其它類(lèi)似的算法)經(jīng)加密后存儲(chǔ)在文件系統(tǒng)中。當(dāng)用戶登錄的時(shí)候,系統(tǒng)把用戶輸入的密碼計(jì)算成MD5值,然后再去和保存在文件系統(tǒng)中的MD5值進(jìn)行比較,進(jìn)而確定輸入的密碼是否正確。通過(guò)這樣的步驟,系統(tǒng)在并不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統(tǒng)的合法性。這不但可以避免用戶的密碼被具有系統(tǒng)管理員權(quán)限的用戶知道,而且還在一定程度上增加了密碼被破解的難度。)
3.防止抵賴(數(shù)字簽名):
這需要一個(gè)第三方認(rèn)證機(jī)構(gòu)。例如A寫(xiě)了一個(gè)文件,認(rèn)證機(jī)構(gòu)對(duì)此文件用MD5算法產(chǎn)生摘要信息并做好記錄。若以后A說(shuō)這文件不是他寫(xiě)的,權(quán)威機(jī)構(gòu)只需對(duì)此文件重新產(chǎn)生摘要信息,然后跟記錄在冊(cè)的摘要信息進(jìn)行比對(duì),相同的話,就證明是A寫(xiě)的了。這就是所謂的“數(shù)字簽名”。
MD5安全性
普遍認(rèn)為MD5是很安全,因?yàn)楸┝ζ平獾臅r(shí)間是一般人無(wú)法接受的。實(shí)際上如果把用戶的密碼MD5處理后再存儲(chǔ)到數(shù)據(jù)庫(kù),其實(shí)是很不安全的。因?yàn)橛脩舻拿艽a是比較短的,而且很多用戶的密碼都使用生日,手機(jī)號(hào)碼,身份證號(hào)碼,電話號(hào)碼等等。或者使用常用的一些吉利的數(shù)字,或者某個(gè)英文單詞。如果我把常用的密碼先MD5處理,把數(shù)據(jù)存儲(chǔ)起來(lái),然后再跟你的MD5結(jié)果匹配,這時(shí)我就有可能得到明文。
總結(jié)
到此這篇關(guān)于Java實(shí)現(xiàn)MD5加密算法的文章就介紹到這了,更多相關(guān)Java MD5加密算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合Mybatis-Plus、Jwt實(shí)現(xiàn)登錄token設(shè)置
Spring Boot整合Mybatis-plus實(shí)現(xiàn)登錄常常需要使用JWT來(lái)生成用戶的token并設(shè)置用戶權(quán)限的攔截器,本文就來(lái)詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02集群環(huán)境中使用ehcache_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了集群環(huán)境中使用ehcache的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08SpringBoot靜態(tài)資源映射規(guī)則淺析
這篇文章主要介紹了SpringBoot靜態(tài)資源映射規(guī)則,今天在玩SpringBoot的demo的時(shí)候,放了張圖片在resources目錄下,啟動(dòng)區(qū)訪問(wèn)的時(shí)候,突然好奇是識(shí)別哪些文件夾來(lái)展示靜態(tài)資源的, 為什么有時(shí)候放的文件夾不能顯示,有的卻可以2023-02-02Java將List轉(zhuǎn)換為String的幾種方式
我們大家在實(shí)際開(kāi)發(fā)中經(jīng)常遇到List轉(zhuǎn)為String字符串的情況,下面這篇文章主要給大家介紹了關(guān)于Java將List轉(zhuǎn)換為String的幾種方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹,本文講解了為什么要使用代理模式、如何使用代理模式等內(nèi)容,需要的朋友可以參考下2015-03-03Java定義隊(duì)列結(jié)構(gòu),并實(shí)現(xiàn)入隊(duì)、出隊(duì)操作完整示例
這篇文章主要介紹了Java定義隊(duì)列結(jié)構(gòu),并實(shí)現(xiàn)入隊(duì)、出隊(duì)操作,結(jié)合完整實(shí)例形式分析了java數(shù)據(jù)結(jié)構(gòu)中隊(duì)列的定義、入隊(duì)、出隊(duì)、判斷隊(duì)列是否為空、打印隊(duì)列元素等相關(guān)操作技巧,需要的朋友可以參考下2020-02-02elasticsearch索引創(chuàng)建create?index集群matedata更新
這篇文章主要介紹了elasticsearch索引創(chuàng)建create?index及集群matedata更新,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04