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"));
}
}
org.bouncycastle:bcprov-jdk15on:1.70Security.addProvider(new BouncyCastleProvider())local_policy.jar、US_export_policy.jar$JAVA_HOME/jre/lib/security/ 下同名檔案// 存入: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 與密文一起儲存。