核心 API 流程
MessageDigest.getInstance("MD5") 獲取實例(工廠模式);
update(byte[]) 輸入數據(可多次調用累積);
digest() 完成計算,返回字節數組(16 字節 MD5,20 字節 SHA-1);
- 字節數組轉十六進制字符串輸出。
完整代碼實現
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class DigestUtil {
public static String md5(String input) {
return digest(input, "MD5");
}
public static String sha1(String input) {
return digest(input, "SHA-1");
}
public static String sha256(String input) {
return digest(input, "SHA-256");
}
private static String digest(String input, String algo) {
try {
MessageDigest md = MessageDigest.getInstance(algo);
md.update(input.getBytes(StandardCharsets.UTF_8));
byte[] hash = md.digest();
return toHex(hash);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("JVM 缺少算法: " + algo, e);
}
}
private static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(md5("abc")); // 900150983cd24fb0d6963f7d28e17f72
}
}
關鍵技術點
- 工廠模式:
MessageDigest 構造器 protected,必須用 getInstance;
- 編碼顯式化:
getBytes(StandardCharsets.UTF_8) 避免平台差異;
- 十六進制轉換:
String.format("%02x", b) 或位運算 (b & 0xFF) 保證無符號;
- 流式處理:大文件可
update(buf, 0, len) 分塊,無需全量載入內存。
常用算法對比
| 算法 | 輸出長度 | 安全性 | 適用場景 |
| MD5 | 128 bit (32 hex) | 已破解(碰撞攻擊) | 文件完整性校驗、非安全場景 |
| SHA-1 | 160 bit (40 hex) | 理論脆弱 | Git 提交 ID、漸進式遷移 |
| SHA-256 | 256 bit (64 hex) | 強 | 數字簽名、區塊鏈、密碼鹽值 |
| SHA-512 | 512 bit (128 hex) | 極強 | 高安全需求、長期有效性 |
安全最佳實踐
- 密碼存儲:禁用 MD5/SHA,必須用
BCrypt、PBKDF2、Argon2 等慢哈希 + 隨機鹽;
- 文件校驗:SHA-256 平衡性能與安全;
- 簽名驗證:配合 RSA/ECDSA 非對稱加密,
Signature 類實現;
- 防長度擴展攻擊:HMAC (
Mac.getInstance("HmacSHA256")) 替代單純哈希。
性能優化
- 實例復用:
MessageDigest 非線程安全,用 ThreadLocal 或每次新建;
- 硬件加速:現代 CPU 支援 SHA-NI 指令集,JVM 自動利用;
- 避免頻繁創建
StringBuilder:靜態編譯正則或預分配容量。