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

解決 DES 加密中文亂碼問題:編碼統一最佳實踐

     編輯:Java 綜合教學

問題背景

在使用 DES 對稱加密處理中文數據時,亂碼是最常見的棘手問題。根本原因在於 字符編碼不一致:加密端、傳輸端、解密端使用了不同的字符集。本文提供標準化解決方案。

核心解決方案:全鏈路 UTF-8 編碼統一

1. 服務端響應設置

在 Servlet/Controller 返回加密數據時,必須在響應頭中明確聲明字符集:

// Spring MVC / Servlet 通用寫法
response.setContentType("application/json; charset=UTF-8");
// 或
response.setCharacterEncoding("UTF-8");

2. 客戶端解碼關鍵代碼

接收加密數據 (通常為 Hex 字符串) 時,需按以下順序處理:

/**
 * 完整解密流程:Hex字符串 → 字節數組 → DES解密 → UTF-8字符串
 * @param hexData  接收到的十六進制加密字符串
 * @param key      解密密鑰
 * @return 解密後的明文字符串
 */
public String decryptFromHex(String hexData, String key) throws Exception {
    // 1. Hex 字符串轉字節數組 (此步驟不涉及字符編碼)
    byte[] encryptedBytes = hexStringToByteArray(hexData);
    
    // 2. DES 解密得到原始字節數組
    byte[] decryptedBytes = DESUtil.decrypt(encryptedBytes, key.getBytes("UTF-8"));
    
    // 3. 關鍵:指定 UTF-8 將字節數組轉為字符串
    return new String(decryptedBytes, "UTF-8");
}

/** Hex 字符串轉字節數組工具方法 */
private byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

亂碼產生的三大典型場景

場景 錯誤做法 正確做法
字符串獲取字節 str.getBytes() (使用平台默認編碼) str.getBytes("UTF-8")
字節轉字符串 new String(bytes) new String(bytes, "UTF-8")
URL 參數傳遞 直接拼接中文或加密後的特殊字符 加密後轉 Hex/Base64 再 URLEncode

完整調用鏈路示例

加密端 (Java 後端)

// 1. 業務數據
String plainText = "用戶名:張三,訂單號:20231001";

// 2. 指定 UTF-8 獲取字節
byte[] data = plainText.getBytes("UTF-8");

// 3. 加密 (密鑰也用 UTF-8)
byte[] encrypted = DESUtil.encrypt(data, "MySecretKey".getBytes("UTF-8"));

// 4. 轉 Hex 字符串便於傳輸
String hexResult = DESUtil.bytesToHex(encrypted);

// 5. 返回給前端 (已設置 response charset=UTF-8)
return Result.success(hexResult);

解密端 (Java 客戶端/其他服務)


進階建議:改用 Base64 編碼

Hex 編碼會使數據體積膨脹 2 倍,建議使用 Base64 編碼替代:

// 加密後編碼
String base64Result = Base64.getEncoder().encodeToString(encryptedBytes);

// 解密前解碼
byte[] encryptedBytes = Base64.getDecoder().decode(base64String);

優勢:體積只增加 33%、標準庫支持、URL 安全變體可直接傳參。

總結

  1. 統一編碼:全鏈路強制使用 UTF-8 (getBytes/ new String 都顯式指定)
  2. 傳輸編碼:加密字節數組必須轉為 Hex 或 Base64 字符串再傳輸
  3. HTTP 層面:請求/響應 Header 明確聲明 charset=UTF-8
  4. 密鑰處理:密鑰字符串獲取字節時同樣指定 UTF-8

遵循以上原則,可徹底消除 DES 加密中的中文亂碼問題。

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