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 中實(shí)現(xiàn) MD5 加密
2.1 JDK 提供的 MD5 算法
Java 中進(jìn)行 MD5 加密使用的是 JDk 中的 java.security
包中的 MessageDigest 類,其中的 getInstance() 方法可以根據(jù)算法名稱獲取對應(yīng)的算法實(shí)例。
// 獲取 MD5 算法實(shí)例對象
MessageDigest md = MessageDigest.getInstance("MD5");
2.2 字符串的 MD5 加密
根據(jù) JDK 提供的算法,可以對任意的字符內(nèi)容進(jìn)行 MD5 加密處理,加密處理的流程為:
-
獲取 MD5 算法實(shí)例
-
獲取需要加密的字符內(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 實(shí)例
-
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 方法中驗(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)險。
public static String md5(String data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
// 加鹽處理,需要將對應(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 值計算
MD5 算法除了用于對字符內(nèi)容進(jìn)行加密,還可以用來對文件進(jìn)行 MD5 校驗(yàn)。
文件進(jìn)行 MD5 校驗(yàn)即針對每個文件可以計算出一個 MD5 值來作為該文件的唯一編碼,如果文件在傳輸過程中發(fā)生了修改,那么最終得到文件的 MD5 值會發(fā)生變化。
根據(jù)上述 MD5 校驗(yàn)方法可以驗(yàn)證文件的有效性,保證文件在傳輸過程中不會被篡改。
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 算法的有效性文章來源:http://www.zghlxwxcb.cn/news/detail-698669.html
public static void main(String[] args) {
String filePath = "C:\桌面\test.jpg";
String fileMd5Str = md5ForFile(filePath);
System.out.println("加密后: " + fileMd5Str);
}
輸出結(jié)果為文章來源地址http://www.zghlxwxcb.cn/news/detail-698669.html
加密后: 75f590a718ee6e8f65c0e7bf780a9e79
到了這里,關(guān)于Java 實(shí)現(xiàn) MD5 加密算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!