在實際項目中,爲了安全性考慮,常常要求帳號密碼是以加密後的密文形式,保存到數據庫中。html
這樣,即便有人獲取到了數據庫中的密文密碼,也不知道明文密碼信息是什麼,從而防止系統被惡意訪問。前端
密碼加密有不少種方式,好比:Base64,DSA,RSA,MD5,SHA128,SHA256,SHA512等加密方式。java
本文主要講述 MD5 加密方式。算法
MD5 消息摘要算法(英文:MD5 Message-Digest Algorithm),一種被普遍使用的密碼散列函數,能夠產生出一個128位(16字節)的散列值(hash value),用於確保信息傳輸完整一致。數據庫
MD5由美國密碼學家羅納德·李維斯特(Ronald Linn Rivest)設計,於1992年公開,用以取代MD4算法。apache
利用它的單向加密性,即不可逆性,咱們能夠應用於數據和密碼的加密。json
因爲MD5算法的單向性,由MD5碼計算出原文幾乎是不可能的。目前對於這種加密方法的破解方式是收集經常使用的密碼形式,例如生日,身份證號,電話號碼等。把這些收集到的祕密用MD5處理以後進行存儲,而後與須要還原的MD5進行比對,當收集的數據達到必定的數目,用戶密碼被破解的可能性就會變得很大。後端
對於這種方法,一種增強安全性的方法就是在對用戶密碼進行MD5處理的時候在原密碼上加一個附近值,例如原密碼爲「password」,處理的時候變爲「passworddrowssap」,通過這樣的處理以後能夠有效下降密碼被破解的可能性。數組
每一個文件均可以計算出一個特定的 MD5 值。安全
好比,咱們上傳一個文件到服務器上,能夠同時計算出該文件對應的 MD5 值;
在文件下載的時候,經過再次計算該文件的 MD5 值。
若是兩個MD5值相同,說明文件沒有變化,不然,說明文件被修改過。
經過Java編寫程序,實現對任意字符串進行 MD5 加密。
代碼以下:
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
代碼以下:
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
代碼以下:
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>
http://www.bejson.com/enc/md5/ (不只支持 MD5加密,還支持 Base64,SHA等)
效果以下(在「加密前」後的輸入框中輸入須要 MD5 加密的字符串 --> 點擊「MD5加密」 --> 便可在「加密後」的顯示顯示框中看到加密後的密文):
效果以下(輸入框中輸入須要解密的 MD5 密文,點擊解密便可解密 ):
2) https://www.cmd5.com/ (這是一款很強大的解密工具,不只支持 MD5,還支持SHA的解密)
效果以下(在密文輸入框中輸入 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 語言實現,請參考博客:http://www.javashuo.com/article/p-bzbracey-bv.html
但願能幫到你們,謝謝!