Java實現(xiàn)MD5加密算法方法例子
1. MD5 加密算法
1.1 MD5 算法介紹
MD5 消息摘要算法,英文:MD5 Message-Digest Algorithm ,一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個128位(16字節(jié))的散列值(hash value),用于確保信息傳輸完整一致。
MD5 是單向加密不可逆的,也就是常說的非對稱加密,常用于用戶密碼的加密,這樣即使密碼泄露也不知道對應(yīng)的明文信息,有效的保護(hù)系統(tǒng)和用戶的隱私信息。
MD5 算法產(chǎn)生的是一個 128 位的散列值,128 位是指的二進(jìn)制中的 128 位,具體占 16 字節(jié)(每個字節(jié)可以表示為 8 位二進(jìn)制數(shù))。
MD5 加密最終會將 128 位數(shù)字轉(zhuǎn)換成十六進(jìn)制表示,每個字節(jié)( 8 位)轉(zhuǎn)成 2 位十六進(jìn)制數(shù),最終得到 32 個字符,其中每兩個字符代表一個十六進(jìn)制數(shù),因此最終 MD5 加密結(jié)果字符長度為 32 位。
1.2 算法加鹽
由于 MD5 算法是單向的,不能被反向解析,但是可以通過正向加密后的字典表(Lookup 表和 Rainbow 表)對比的方式進(jìn)行暴力破解。
對于此種情況可以使用自定義偏移常量(鹽值)的方法來降低加密結(jié)果被破解的可能。
2. Java 中實現(xiàn) MD5 加密
2.1 JDK 提供的 MD5 算法
Java 中進(jìn)行 MD5 加密使用的是 JDk 中的 java.security
包中的 MessageDigest 類,其中的 getInstance() 方法可以根據(jù)算法名稱獲取對應(yīng)的算法實例。
// 獲取 MD5 算法實例對象 MessageDigest md = MessageDigest.getInstance("MD5");
2.2 字符串的 MD5 加密
根據(jù) JDK 提供的算法,可以對任意的字符內(nèi)容進(jìn)行 MD5 加密處理,加密處理的流程為:
獲取 MD5 算法實例
獲取需要加密的字符內(nèi)容對應(yīng)的的字節(jié)信息,可指定編碼方式
對得到的字節(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 個字符 StringBuilder sb = new StringBuilder(); for (byte b : md5) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
MessageDigest 類可以獲取 MD5 實例
md.digest() 計算字符串內(nèi)容的摘要,并得到計算后的 hash value
StandardCharsets.UTF_8 用來指定計算時使用的編碼格式,如果不指定則會使用系統(tǒng)默認(rèn)編碼格式,系統(tǒng)之間不統(tǒng)一會造成中文亂碼
sb.append(String.format(“%02x”, b)) 用于將字節(jié)信息轉(zhuǎn)為十六進(jìn)制
最后,可以在 main 方法中驗證 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)險。
public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); // 加鹽處理,需要將對應(yīng)的鹽記錄,用于驗證密碼 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 值計算
MD5 算法除了用于對字符內(nèi)容進(jìn)行加密,還可以用來對文件進(jìn)行 MD5 校驗。
文件進(jìn)行 MD5 校驗即針對每個文件可以計算出一個 MD5 值來作為該文件的唯一編碼,如果文件在傳輸過程中發(fā)生了修改,那么最終得到文件的 MD5 值會發(fā)生變化。
根據(jù)上述 MD5 校驗方法可以驗證文件的有效性,保證文件在傳輸過程中不會被篡改。
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 方法中驗證 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ā)送一個電子文檔,發(fā)送前,我先得到MD5的輸出結(jié)果a。然后在對方收到電子文檔后,對方也得到一個MD5的輸出結(jié)果b。如果a與b一樣就代表中途未被篡改。
2)比如我提供文件下載,為了防止不法分子在安裝程序中添加木馬,我可以在網(wǎng)站上公布由安裝文件得到的MD5輸出結(jié)果。
3)SVN在檢測文件是否在CheckOut后被修改過,也是用到了MD5.
2.防止直接看到明文:
現(xiàn)在很多網(wǎng)站在數(shù)據(jù)庫存儲用戶的密碼的時候都是存儲用戶密碼的MD5值。這樣就算不法分子得到數(shù)據(jù)庫的用戶密碼的MD5值,也無法知道用戶的密碼。(比如在UNIX系統(tǒng)中用戶的密碼就是以MD5(或其它類似的算法)經(jīng)加密后存儲在文件系統(tǒng)中。當(dāng)用戶登錄的時候,系統(tǒng)把用戶輸入的密碼計算成MD5值,然后再去和保存在文件系統(tǒng)中的MD5值進(jìn)行比較,進(jìn)而確定輸入的密碼是否正確。通過這樣的步驟,系統(tǒng)在并不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統(tǒng)的合法性。這不但可以避免用戶的密碼被具有系統(tǒng)管理員權(quán)限的用戶知道,而且還在一定程度上增加了密碼被破解的難度。)
3.防止抵賴(數(shù)字簽名):
這需要一個第三方認(rèn)證機(jī)構(gòu)。例如A寫了一個文件,認(rèn)證機(jī)構(gòu)對此文件用MD5算法產(chǎn)生摘要信息并做好記錄。若以后A說這文件不是他寫的,權(quán)威機(jī)構(gòu)只需對此文件重新產(chǎn)生摘要信息,然后跟記錄在冊的摘要信息進(jìn)行比對,相同的話,就證明是A寫的了。這就是所謂的“數(shù)字簽名”。
MD5安全性
普遍認(rèn)為MD5是很安全,因為暴力破解的時間是一般人無法接受的。實際上如果把用戶的密碼MD5處理后再存儲到數(shù)據(jù)庫,其實是很不安全的。因為用戶的密碼是比較短的,而且很多用戶的密碼都使用生日,手機(jī)號碼,身份證號碼,電話號碼等等?;蛘呤褂贸S玫囊恍┘臄?shù)字,或者某個英文單詞。如果我把常用的密碼先MD5處理,把數(shù)據(jù)存儲起來,然后再跟你的MD5結(jié)果匹配,這時我就有可能得到明文。
總結(jié)
到此這篇關(guān)于Java實現(xiàn)MD5加密算法的文章就介紹到這了,更多相關(guān)Java MD5加密算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus 分頁插件配置的兩種方式實現(xiàn)
本文主要介紹了MyBatis-Plus 分頁插件配置的兩種方式實現(xiàn),包括使用PaginationInterceptor和MybatisPlusInterceptor兩種方式,具有一定的參考價值,感興趣的可以了解一下2025-03-03spring事務(wù)隔離級別、傳播機(jī)制以及簡單配置方式
這篇文章主要介紹了spring事務(wù)隔離級別、傳播機(jī)制以及簡單配置方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01