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

Java 字串壓縮加密實戰:GZIP + DES 組合範例

     編輯:Java 相關知識

需求背景

傳輸敏感 JSON/文字資料時,常需**壓縮減小體積** + **加密保護機密**。本文示範 GZIP 壓縮 + DES 對稱加密 的經典組合,並提供可直接使用的工具類。

⚠️ 安全提醒:DES 金鑰僅 56 位,現代標準視為**不安全** (易暴力破解)。生產環境**必須改用 AES-256-GCM**。本文僅供教學示範組合流程。

完整工具類

1. GZIP 壓縮/解壓 (ZipUtil)


import java.io.*;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public final class ZipUtil {
    private ZipUtil() {}

    /** 字串壓縮 → Base64 字串 (便於傳輸) */
    public static String compress(String str) throws IOException {
        if (str == null || str.isEmpty()) return str;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzos = new GZIPOutputStream(bos)) {
            gzos.write(str.getBytes(StandardCharsets.UTF_8));
        }
        return Base64.getEncoder().encodeToString(bos.toByteArray());
    }

    /** Base64 字串解壓 → 原字串 */
    public static String decompress(String base64) throws IOException {
        if (base64 == null || base64.isEmpty()) return base64;
        byte[] compressed = Base64.getDecoder().decode(base64);
        try (ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
             GZIPInputStream gis = new GZIPInputStream(bis);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = gis.read(buf)) > 0) bos.write(buf, 0, len);
            return bos.toString(StandardCharsets.UTF_8);
        }
    }
}

2. DES 加密/解密 (DesUtil)


import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

public final class DesUtil {
    private static final String ALGO = "DES";
    private static final String KEY = "MZTHPWDJM"; // 8 位元組金鑰
    private DesUtil() {}

    public static String encrypt(String data) throws Exception {
        return encrypt(data, KEY);
    }
    public static String decrypt(String data) throws Exception {
        return decrypt(data, KEY);
    }

    public static String encrypt(String data, String key) throws Exception {
        byte[] encrypted = doFinal(data.getBytes(StandardCharsets.UTF_8), key, Cipher.ENCRYPT_MODE);
        return Base64.getEncoder().encodeToString(encrypted);
    }

    public static String decrypt(String data, String key) throws Exception {
        byte[] decoded = Base64.getDecoder().decode(data);
        byte[] decrypted = doFinal(decoded, key, Cipher.DECRYPT_MODE);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    private static byte[] doFinal(byte[] input, String key, int mode) throws Exception {
        DESKeySpec dks = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory kf = SecretKeyFactory.getInstance(ALGO);
        SecretKey sk = kf.generateSecret(dks);
        Cipher cipher = Cipher.getInstance(ALGO);
        cipher.init(mode, sk, new SecureRandom());
        return cipher.doFinal(input);
    }
}

3. 組合使用範例


public class CryptoDemo {
    public static void main(String[] args) throws Exception {
        String original = "這是一段需要壓縮加密的測試資料,包含中文、數字123、符號!@#。";
        System.out.println("原文長度: " + original.length());

        // 壓縮 → 加密
        String compressed = ZipUtil.compress(original);
        System.out.println("壓縮後 Base64 長度: " + compressed.length());

        String encrypted = DesUtil.encrypt(compressed);
        System.out.println("加密後 Base64 長度: " + encrypted.length());

        // 解密 → 解壓
        String decrypted = DesUtil.decrypt(encrypted);
        System.out.println("解密後 Base64 長度: " + decrypted.length());

        String restored = ZipUtil.decompress(decrypted);
        System.out.println("還原後長度: " + restored.length());
        System.out.println("內容一致: " + original.equals(restored));
    }
}

實測資料 (範例輸出)

原文長度: 78
壓縮後 Base64 長度: 88  (短字串壓縮反而變大,含 Header 開銷)
加密後 Base64 長度: 124
解密後 Base64 長度: 88
還原後長度: 78
內容一致: true

長文本 (如 10KB JSON) 壓縮率通常達 70%~90%。

生產級強化指南

AES-256-GCM 現代替代碼片段


public static String encryptAes(String data, byte[] key) throws Exception {
    byte[] nonce = new byte[12]; new SecureRandom().nextBytes(nonce);
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(128, nonce));
    byte[] cipherText = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
    // 組合: nonce(12) + cipherText
    byte[] combined = new byte[nonce.length + cipherText.length];
    System.arraycopy(nonce, 0, combined, 0, nonce.length);
    System.arraycopy(cipherText, 0, combined, nonce.length, cipherText.length);
    return Base64.getEncoder().encodeToString(combined);
}

理解「壓縮 → 加密 → Base64」管道化處理流程,並認清 DES 缺陷升級 AES-GCM,是 Java 開發者資安基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
項目現狀建議升級
加密演算法DES (56-bit)AES-256-GCM (Authenticated Encryption)
金鑰管理硬編碼字串環境變數 / Vault / AWS KMS / HashiCorp Vault
IV/NonceDES 隨機 (ECB 模式隱性)AES-GCM 需唯一 Nonce (12 位元組),隨機產生並隨密文儲存
壓縮副作用CRIME/BREACH 攻擊風險敏感資料**先加密再壓縮**無效;建議**僅加密不壓縮**,或使用固定長度填充
完整性驗證無AES-GCM 內建標籤驗證;若用 CBC 需額外 HMAC