基於 MessageDigest 實現 MD5 加密,提供加密與驗證兩大核心功能,含十六進位轉換細節處理。
package com.sunnylocus.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CipherUtil {
private static final String[] HEX_DIGITS =
{"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
/** 加密輸入字串 */
public static String generatePassword(String input) {
return encodeByMD5(input);
}
/** 驗證明文與密文是否匹配 */
public static boolean validatePassword(String encrypted, String plain) {
return encrypted != null && encrypted.equals(encodeByMD5(plain));
}
private static String encodeByMD5(String origin) {
if (origin == null) return null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] result = md.digest(origin.getBytes(StandardCharsets.UTF_8));
return byteArrayToHexString(result).toUpperCase();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm not available", e);
}
}
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte b : bytes) sb.append(byteToHexString(b));
return sb.toString();
}
private static String byteToHexString(byte b) {
int n = b & 0xFF; // 無符號轉換
return HEX_DIGITS[n >>> 4] + HEX_DIGITS[n & 0x0F];
}
}
public class Main {
public static void main(String[] args) {
String plain = "123";
String encrypted = CipherUtil.generatePassword(plain);
System.out.println("明文: " + plain);
System.out.println("密文: " + encrypted); // 202CB962AC59075B964B07152D234B70
System.out.println("驗證: " + CipherUtil.validatePassword(encrypted, plain)); // true
System.out.println("驗證錯誤: " + CipherUtil.validatePassword(encrypted, "456")); // false
}
}
BCrypt (Spring Security BCryptPasswordEncoder)、Argon2、PBKDF2SHA-256、SHA-3MessageDigest.isEqual() (Java 9+) 或恆定時間比較
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10); // strength=10
String hashed = encoder.encode("123"); // 自動加鹽
boolean matches = encoder.matches("123", hashed); // 防時序攻擊