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

Java 加密工具類:DES 對稱加密與 Base64 編碼實作

     編輯:Java 相關知識

前言

資料加密與編碼是系統安全的基礎設施。本文提供兩個生產級工具類:DESUtil 實作 DES 對稱加密/解密(含 Base64 編碼輸出),Base64 實作標準 Base64 編碼/解碼(支援字串、位元組陣列、檔案)。程式碼基於 JDK 標準加密 API,無第三方依賴。

DESUtil - DES 加密工具類

核心特性

  • DES/ECB/PKCS5Padding 模式(預設)
  • 密鑰可自訂,預設使用字元池
  • 加密結果自動 Base64 編碼,便於傳輸儲存
  • 支援指定字元集(預設 UTF-8)

關鍵實作解析

1. 密鑰生成策略

private String keyData = "ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz0123456789-_.";

private byte[] getKey() {
    SecureRandom sr = new SecureRandom();
    KeyGenerator kg = KeyGenerator.getInstance("DES");
    kg.init(sr);
    SecretKey key = kg.generateKey();
    return key.getEncoded(); // 注意:每次生成不同密鑰!
}

關鍵缺陷:getKey() 每次調用生成新密鑰,導致加密解密密鑰不一致!原作者在註釋中已標註廢棄。

2. 正確加密流程

public String encrypt(String source, String charSet) throws UnsupportedEncodingException {
    byte[] ret = encrypt(source.getBytes(charSet)); // 原始加密
    return new String(Base64.encode(ret));          // Base64 編碼
}

private byte[] encrypt(byte[] primaryData) {
    // 1. 建立 DESKeySpec(使用固定 keyData)
    DESKeySpec dks = new DESKeySpec(keyData.getBytes());
    // 2. 密鑰工廠生成 SecretKey
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey key = keyFactory.generateSecret(dks);
    // 3. Cipher 初始化加密模式
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.ENCRYPT_MODE, key, new SecureRandom());
    // 4. 執行加密
    return cipher.doFinal(primaryData);
}

3. 解密流程

public String decrypt(String encryptedData, String charSet) 
    throws UnsupportedEncodingException {
    byte[] ret = descrypt(Base64.decode(encryptedData.toCharArray()));
    return new String(ret, charSet);
}

private byte[] descrypt(byte[] encryptedData) {
    // 同加密流程,但 Cipher.init 使用 DECRYPT_MODE
    DESKeySpec dks = new DESKeySpec(keyData.getBytes());
    SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.DECRYPT_MODE, key, new SecureRandom());
    return cipher.doFinal(encryptedData);
}

使用範例

DESUtil des = new DESUtil("MySecretKey8"); // 8 字元密鑰

String plain = "敏感資料加密測試";
String encrypted = des.encrypt(plain);      // 加密 + Base64
String decrypted = des.decrypt(encrypted);  // Base64 解碼 + 解密

System.out.println("原文: " + plain);
System.out.println("密文: " + encrypted);
System.out.println("解密: " + decrypted);

安全性警示

  • DES 已不安全:56 位鍵長易遭暴力破解,生產環境請用 AES-256
  • ECB 模式缺陷:相同明文產生相同密文,建議使用 CBC/GCM 模式
  • 密鑰管理:勿硬編碼密鑰,應使用金鑰管理系統(KMS)或環境變數

Base64 - 編碼解碼工具類

核心功能

  • 字串/位元組陣列/字元陣列編碼解碼
  • 檔案編碼/解碼(流式處理,支援大檔案)
  • 標準 Base64 字元表(A-Z, a-z, 0-9, +, /, =)

關鍵實作

private static final char[] ALPHABET = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
private static final byte[] CODES = new byte[256]; // 解碼查找表

static {
    Arrays.fill(CODES, (byte) -1);
    for (int i = 'A'; i <= 'Z'; i++) CODES[i] = (byte) (i - 'A');
    for (int i = 'a'; i <= 'z'; i++) CODES[i] = (byte) (26 + i - 'a');
    for (int i = '0'; i <= '9'; i++) CODES[i] = (byte) (52 + i - '0');
    CODES['+'] = 62; CODES['/'] = 63; CODES['='] = 0;
}

// 編碼位元組陣列
public static char[] encode(byte[] data) {
    char[] out = new char[((data.length + 2) / 3) * 4];
    for (int i = 0, idx = 0; i < data.length; i += 3, idx += 4) {
        int val = (data[i] & 0xFF) << 16;
        if (i + 1 < data.length) val |= (data[i+1] & 0xFF) << 8;
        if (i + 2 < data.length) val |= (data[i+2] & 0xFF);
        out[idx+3] = ALPHABET[(i+2 < data.length) ? (val & 0x3F) : 64];
        val >>= 6;
        out[idx+2] = ALPHABET[(i+1 < data.length) ? (val & 0x3F) : 64];
        val >>= 6;
        out[idx+1] = ALPHABET[val & 0x3F];
        val >>= 6;
        out[idx] = ALPHABET[val & 0x3F];
    }
    return out;
}

// 解碼字元陣列
public static byte[] decode(char[] data) {
    // 計算有效長度、分配輸出緩衝區、逐字元解碼還原位元組
    // ... 核心邏輯:累積 6 位,每滿 8 位輸出一字節
}

檔案處理

public static void encode(File file) throws IOException {
    byte[] decoded = readBytes(file);
    char[] encoded = encode(decoded);
    writeChars(file, encoded); // 覆蓋原檔案
}

public static void decode(File file) throws IOException {
    char[] encoded = readChars(file);
    byte[] decoded = decode(encoded);
    writeBytes(file, decoded);
}

使用範例

// 字串編碼
String encoded = Base64.encode("Hello World"); // SGVsbG8gV29ybGQ=
String decoded = Base64.decode(encoded);       // Hello World

// 檔案編碼(圖片轉 Base64 字串)
Base64.encode(new File("image.png")); // 檔案內容變為 Base64 文本
Base64.decode(new File("image.png")); // 還原二進位

現代替代方案建議

需求推薦方案優勢
對稱加密AES-GCM (JDK 8+)認證加密、效能佳、256位安全
Base64java.util.Base64 (JDK 8+)標準庫、支援 Basic/URL/MIME、無依賴
密碼雜湊BCrypt / Argon2自帶鹽值、可調計算成本、抗彩虹表

線上工具參考

總結

本文提供的 DESUtil 與 Base64 工具類代碼結構完整、功能齊全,適合學習加密編碼原理。但受限於演算法老舊(DES、ECB 模式)、密鑰管理缺陷,**嚴禁用於生產環境敏感資料加密**。現代專案請直接使用 JDK 8+ 內建 java.util.Base64 及 javax.crypto AES-GCM 實作。

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