首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 字串與密碼加密實作:MD5 兩種寫法完整比較

     編輯:Java 相關知識

應用場景

  • 使用者密碼**不可逆**儲存(資料庫存雜湊值)。
  • API 簽名驗證、資料完整性校驗。
  • 敏感資訊(身分證、手機號)脫敏顯示。

方案一:工具類封裝(適合專案統一引用)

package com.tnt.util;

import java.security.MessageDigest;

public class StringUtil {
    private static final char[] HEX = "0123456789abcdef".toCharArray();

    /** 位元組陣列轉 16 進位字串 */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            sb.append(HEX[(b >> 4) & 0x0f]);
            sb.append(HEX[b & 0x0f]);
        }
        return sb.toString();
    }

    /** MD5 加密,回傳 32 位小寫 16 進位字串 */
    public static String md5Encode(String origin) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return bytesToHex(md.digest(origin.getBytes("UTF-8")));
        } catch (Exception e) {
            throw new RuntimeException("MD5 計算失敗", e);
        }
    }

    public static void main(String[] args) {
        System.out.println(md5Encode("123456")); // e10adc3949ba59abbe56e057f20f883e
    }
}

方案二:單一方法完整實作(無額外依賴)

package com.shangyu.core.utils;

public class MD5 {
    private static final char[] HEX = "0123456789abcdef".toCharArray();

    public static String getMD5(byte[] source) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            md.update(source);
            byte[] digest = md.digest();
            char[] chars = new char[32];
            int k = 0;
            for (byte b : digest) {
                chars[k++] = HEX[(b >>> 4) & 0x0f];
                chars[k++] = HEX[b & 0x0f];
            }
            return new String(chars);
        } catch (Exception e) {
            throw new RuntimeException("MD5 計算失敗", e);
        }
    }

    public static String getMD5(String str) {
        return getMD5(str.getBytes(java.nio.charset.StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        System.out.println(getMD5("123456"));
    }
}

關鍵差異比較

項目方案一方案二
程式碼結構分離 bytesToHex 可複用單一方法內完成,複製即用
字元編碼明確指定 UTF-8使用 StandardCharsets.UTF_8(Java 7+)
異常處理包裝為 RuntimeException同
效能相同(皆用 MessageDigest)相同

安全性補充:MD5 已不建議用於密碼儲存

  • MD5 速度極快,易遭暴力破解(GPU 可達每秒百億次)。
  • **生產環境請改用**:
    • BCrypt(BCrypt.hashpw(),內建鹽值、可調成本因子)
    • PBKDF2(SecretKeyFactory,NIST 標準)
    • Argon2(記憶體硬化,防 ASIC 破解)
  • 若必須用 MD5(如對接舊系統),**務必加鹽**:md5(salt + password + salt),鹽值每用戶唯一並存資料庫。

完整加鹽 MD5 範例

public static String md5WithSalt(String password, String salt) {
    return md5Encode(salt + password + salt);
}

// 產生隨機鹽值
public static String generateSalt() {
    byte[] salt = new byte[16];
    new java.security.SecureRandom().nextBytes(salt);
    return bytesToHex(salt);
}

總結

本文提供兩種風格的 MD5 實作,滿足快速複製與工具類封裝不同需求。**切記:密碼儲存請棄用 MD5,改用 BCrypt/PBKDF2/Argon2 並加鹽**,才能達到現代安全基準。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved