MD5 (Message-Digest Algorithm 5) 由 MIT 與 RSA Data Security 設計,將任意長度位元組串列轉換為 128-bit (32 字元十六進位) 雜湊值。特性:
| 場景 | 說明 | |
|---|---|---|
| 檔案完整性驗證 | 下載檔案對比 MD5 指紋,防篡改 | |
| 密碼儲存 | 資料庫存 MD5 雜湊而非明文,駭客入侵也無法直接得知密碼 | |
| 數位簽名 | 搭配非對稱加密,實現防抵賴 | |
| 快取鍵值 | 長字串轉短固定鍵,如 URL 縮短、查詢快取 |
| C 運算 | Java 運算 | 說明 |
|---|---|---|
a << n | a << n | 左移相同 |
a >> n (unsigned) | a >>> n | Java 無符號右移用 >>> |
a & b | a & b | 位元 AND |
a | b | a | b | 位元 OR |
a ^ b | a ^ b | 位元 XOR |
~a | ~a | 位元 NOT |
// C: #define F(x,y,z) ((x & y) | (~x & z))
// Java: final static 方法
private static int F(int x, int y, int z) {
return (x & y) | (~x & z);
}
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
編譯執行:javac -d . MD5.java && java beartool.MD5,輸出與標準測試向量完全一致。
將 MD5.class 複製至 Linux + IBM JDK 1.3 環境執行,結果相同,確認「一次編寫,到處執行」特性。
Java 版 MD5 計算「一閃即完成」,肉眼無法察覺比 C 版慢。JDK 1.3 JIT 編譯器已能有效優化密集整數運算迴路。
beartool/
└── MD5.class
import beartool.MD5;
public class PasswordService {
public String hashPassword(String plain) {
MD5 md5 = new MD5();
md5.update(plain.getBytes());
return md5.getHashHex(); // 取得 32 字元十六進位字串
}
public boolean verify(String plain, String storedHash) {
return hashPassword(plain).equalsIgnoreCase(storedHash);
}
}
beartool/MD5.class 相對路徑.jar 或 .warmd5-bean.jar 供多專案共用BCryptPasswordEncoder 或 BouncyCastle本文展示從 RFC 1321 參考 C 代碼移植 Pure Java MD5 Bean 的完整過程,驗證了 Java 跨平台特性與運算效能。雖然 MD5 在密碼學應用上已退役,但其演算法移植技巧(無符號模擬、位元運算對應、測試向量驗證)對實作其他雜湊函數(SHA 系列)、加密演算法極具參考價值。