Java 語言實現 MD5 加密
背景說明
在實際項目中,為了安全性考慮,經常要求賬號密碼是以加密后的密文形式,保存到數據庫中。
這樣,即使有人獲取到了數據庫中的密文密碼,也不知道明文密碼信息是什么,從而防止系統被惡意訪問。
密碼加密有很多種方式,比如:Base64,DSA,RSA,MD5,SHA128,SHA256,SHA512等加密方式。
本文主要講述 MD5 加密方式。
MD5 簡介
MD5 消息摘要算法(英文:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數,可以產生出一個128位(16字節)的散列值(hash value),用於確保信息傳輸完整一致。
MD5由美國密碼學家羅納德·李維斯特(Ronald Linn Rivest)設計,於1992年公開,用以取代MD4算法。
MD5應用
1、數據加密
利用它的單向加密性,即不可逆性,我們可以應用於數據和密碼的加密。
由於MD5算法的單向性,由MD5碼計算出原文幾乎是不可能的。目前對於這種加密方法的破解方式是收集常用的密碼形式,例如生日,身份證號,電話號碼等。把這些收集到的秘密用MD5處理之后進行存儲,然后與需要還原的MD5進行比對,當收集的數據達到一定的數目,用戶密碼被破解的可能性就會變得很大。
對於這種方法,一種加強安全性的方法就是在對用戶密碼進行MD5處理的時候在原密碼上加一個附近值,例如原密碼為“password”,處理的時候變為“passworddrowssap”,經過這樣的處理之后可以有效降低密碼被破解的可能性。
2、確認文件是否被篡改
每個文件都可以計算出一個特定的 MD5 值。
比如,我們上傳一個文件到服務器上,可以同時計算出該文件對應的 MD5 值;
在文件下載的時候,通過再次計算該文件的 MD5 值。
如果兩個MD5值相同,說明文件沒有變化,否則,說明文件被修改過。
Java 語言實現 MD5 加密
通過Java編寫程序,實現對任意字符串進行 MD5 加密。
1、第一版代碼(初始版)
代碼如下:
package com.miracle.luna.md5; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5UtilOriginal { /** * 將數據進行 MD5 加密,並以16進制字符串格式輸出 * @param data * @return */ public static String md5(String data) { try { byte[] md5 = md5(data.getBytes("utf-8")); return toHexString(md5); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } /** * 將字節數組進行 MD5 加密 * @param data * @return */ public static byte[] md5(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("md5"); return md.digest(data); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return new byte[]{}; } /** * 將加密后的字節數組,轉換成16進制的字符串 * @param md5 * @return */ private static String toHexString(byte[] md5) { StringBuilder sb = new StringBuilder(); System.out.println("md5.length: " + md5.length); for (byte b : md5) { sb.append(Integer.toHexString(b & 0xff)); } return sb.toString(); } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
運行結果如下:
md5.length: 16
==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
2、第二版代碼(精簡版)
代碼如下:
package com.miracle.luna.md5; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5UtilSimple { /** * 將數據進行 MD5 加密,並以16進制字符串格式輸出 * @param data * @return */ public static String md5(String data) { StringBuilder sb = new StringBuilder(); try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(data.getBytes(StandardCharsets.UTF_8)); // 將字節數據轉換為十六進制 for (byte b : md5) { sb.append(Integer.toHexString(b & 0xff)); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return sb.toString(); } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
運行結果如下:
==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
3、第三版代碼(最終優化版)
代碼如下:
package com.miracle.luna.md5; // 此處需要引入 commons-codec-1.13.jar import org.apache.commons.codec.binary.Hex; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by Miracle Luna on 2019/11/18 */ public class Md5Util { /** * 將數據進行 MD5 加密,並以16進制字符串格式輸出 * @param data * @return */ public static String md5(String data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); return Hex.encodeHexString(md.digest(data.getBytes(StandardCharsets.UTF_8))); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static void main(String[] args) { String password = "password"; String md5HexStr = md5(password); System.out.println("==> MD5 加密前: " + password); System.out.println("==> MD5 加密后: " + md5HexStr); } }
運行結果如下:
==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99
commons-codec-1.13.jar 的 pom 引用如下:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.13</version> </dependency>
MD5 在線加密&解密工具
1、MD5 在線加密工具
http://www.bejson.com/enc/md5/ (不僅支持 MD5加密,還支持 Base64,SHA等)
效果如下(在“加密前”后的輸入框中輸入需要 MD5 加密的字符串 --> 點擊“MD5加密” --> 即可在“加密后”的顯示顯示框中看到加密后的密文):
2、MD5 在線解密
效果如下(輸入框中輸入需要解密的 MD5 密文,點擊解密即可解密 ):
2) https://www.cmd5.com/ (這是一款很強大的解密工具,不僅支持 MD5,還支持SHA的解密)
效果如下(在密文輸入框中輸入 MD5 密文,點擊“解密”,即可看到 MD5 的明文):
解密種類眾多,選擇范圍如下:
MD5 密碼安全性優化
由於現在直接將密碼用 MD5 算法加密存在一定的安全隱患(被暴力破解的可能性),我們可以根據實際的需要,對密碼加密的過程做一些邏輯處理。
比如,如下邏輯處理:
1)password --> Base64 加密,得到加密后的密碼A;
2)password --> 翻轉得到drowssap --> MD5 加密,得到加密后的密碼B;
3)密碼A+密碼B拼接 --> MD5 加密,得到加密后的密碼C;
4)密碼C --> 翻轉操作,產生密碼D,作為最終的密文密碼存到數據庫中。
這樣可以增強密碼的安全性,減少被破解的可能性。(此處具體的邏輯優化,可以根據個人喜好和實際需求,靈活定義其變換的復雜性)。
【額外補充】
當密碼以 MD5 密文存入到數據庫中,用戶登錄的時候,前端將用戶輸入的明文密碼傳輸給后端。
后端程序用同樣的處理邏輯對其進行 MD5 加密,用加密后的密碼與數據庫中該用戶的密文密碼比較。
如果二者相等,說明用戶輸入的密碼正確,允許訪問系統;否則,說明密碼不正確,禁止訪問。
另外,為了系統的安全性考慮,防止惡意暴力嘗試破解密碼,我們經常限制用戶輸入密碼錯誤的次數。
比如,連續輸入3次或者5次密碼,將會自動鎖定賬號一段時間(根據實際場景,設置鎖定時長)。
關於 Base64 加密&解密 的Java 語言實現,請參考博客:https://www.cnblogs.com/miracle-luna/p/11128734.html
希望能幫到大家,謝謝!