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

Java 實現 AES-256 加密解密完整實戰:BouncyCastle、JCE 無限制策略與 Base64 儲存方案

     編輯:Java 相關知識

完整代碼實作

public class AES256Encryption {
    public static final String KEY_ALGORITHM = "AES";
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding"; // 需 BouncyCastle

    // 生成隨機 256-bit 密鑰
    public static byte[] initKey() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
        kg.init(256); // AES-256
        return kg.generateKey().getEncoded();
    }

    // 固定密鑰(生產環境勿硬編碼)
    public static byte[] initRootKey() {
        return new byte[] {
            0x08,0x08,0x04,0x0B,0x02,0x0F,0x0B,0x0C,
            0x01,0x03,0x09,0x07,0x0C,0x03,0x07,0x0A,
            0x04,0x0F,0x06,0x0F,0x0E,0x09,0x05,0x01,
            0x0A,0x0A,0x01,0x09,0x06,0x07,0x09,0x0D
        }; // 32 bytes = 256 bits
    }

    public static Key toKey(byte[] key) {
        return new SecretKeySpec(key, KEY_ALGORITHM);
    }

    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        cipher.init(Cipher.ENCRYPT_MODE, k);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        cipher.init(Cipher.DECRYPT_MODE, k);
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        String str = "芸sweet";
        System.out.println("原文:" + str);

        byte[] key = initRootKey(); // 或 initKey()
        System.out.print("密鑰:");
        for (byte b : key) System.out.printf("%02X", b);
        System.out.println();

        byte[] encrypted = encrypt(str.getBytes("UTF-8"), key);
        System.out.print("密文:");
        for (byte b : encrypted) System.out.printf("%02X", b);
        System.out.println();

        byte[] decrypted = decrypt(encrypted, key);
        System.out.println("解密:" + new String(decrypted, "UTF-8"));
    }
}

⚠️ 兩大必要配置(否則報 InvalidKeyException)

  1. 引入 BouncyCastle Provider
    • Maven: org.bouncycastle:bcprov-jdk15on:1.70
    • 代碼中註冊:Security.addProvider(new BouncyCastleProvider())
  2. 替換 JCE 無限制策略檔案
    • 下載 local_policy.jar、US_export_policy.jar
    • 替換 $JAVA_HOME/jre/lib/security/ 下同名檔案
    • 若用 IDE 內建 JDK,找到對應路徑替換(如 MyEclipse: Window→Preferences→Java→Installed JREs)

密鑰儲存資料庫:Base64 編碼

// 存入:byte[] → Base64 String
String keyStr = Base64.getEncoder().encodeToString(key);

// 取出:Base64 String → byte[]
byte[] key = Base64.getDecoder().decode(keyStr);

資料庫欄位用 VARCHAR 或 TEXT 儲存字串形式密鑰。

模式選擇建議

模式特點適用場景
ECB無 IV、相同明文產生相同密文、不安全測試、極小資料
CBC需 IV、相同明文產生不同密文、推薦生產環境標準選擇
GCM認證加密、防篡改、效能最好高安全需求、現代應用首選

生產建議:使用 AES/GCM/NoPadding 或 AES/CBC/PKCS5Padding + 隨機 IV,IV 與密文一起儲存。

線上工具參考

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