MD5 雖非加密算法,但在 J2ME 中是**完整性校驗、唯一標識生成、非敏感數據指紋**的標準工具。標準庫無 MD5,需自行實現或引入輕量實現。本文提供經過真機驗證的 MD5Digest 類。
public class MD5Digest {
// 單次計算
public static byte[] hash(byte[] input);
public static String hashHex(byte[] input); // 32 位十六進制字符串
// 流式計算 (大文件/網絡流)
public MD5Digest(); // 初始化上下文
public void update(byte[] data, int offset, int len);
public void update(byte b);
public byte[] digest(); // 完成並返回 16 字節摘要
public String digestHex(); // 完成並返回 32 字符十六進制
public void reset(); // 重置上下文復用實例
}
int 運算配合 & 0xFFFFFFFF 模擬 32 位無符號溢出行為。int 狀態 + 64 字節緩衝區 + 長度計數器,實例 < 200 字節。char[] HEX = "0123456789abcdef".toCharArray(),查表轉換無分支。
// 1. 文件/資源完整性校驗
byte[] data = loadResource("/level1.map");
String expected = "a1b2c3d4e5f6..."; // 發布時預計算
if (!MD5Digest.hashHex(data).equals(expected)) {
throw new SecurityException("Resource corrupted");
}
// 2. 生成唯一設備/會話 ID
String imei = System.getProperty("com.nokia.mid.imei"); // 廠商擴展
String sessionId = MD5Digest.hashHex((imei + System.currentTimeMillis()).getBytes());
// 3. 簡單防篡改協議 (客戶端)
byte[] payload = serialize(gameState);
byte[] mac = MD5Digest.hash(concat(payload, secretKey)); // 非 HMAC,僅簡單場景
send(concat(payload, mac));
// 4. 密碼存儲 (必須加鹽!)
String salt = generateRandomSalt(8);
String pwdHash = MD5Digest.hashHex(concat(salt, password).getBytes());
store(salt + ":" + pwdHash); // 驗證時同樣拼接鹽值計算
MD5Digest.java (單文件、< 200 行、零依賴、含自測 main) 可從項目倉庫下載。已在 Nokia S40/S60、Siemens、Motorola、SonyEricsson 真機批量驗證輸出與標準實現 (Java SE MessageDigest) 完全一致。
MD5Digest 為 J2ME 提供了標準、輕量、高性能的哈希能力。正確認清「單向指紋、非加密、非強安全」定位,在合適場景大膽使用,避開安全陷阱。