iT邦幫忙

0

應用系統建置前準備工具 - Aes256Utils 加密解密工具

  • 分享至 

  • xImage
  •  

Aes256Utils 加密解密工具類別

概述

Aes256Utils 是一個提供 AES-256 加密和解密功能的工具類別,使用 CBC 模式和 PKCS5Padding 填充。此類別設計為靜態工具類別,不允許建立實例。

專案相關程式

  • GlobalConstants
  • TypeConvert

第三方元件(Dependency)

  • org.apache.commons.lang3

主要功能

1. AES-256 加密

  • 支援將明文字串加密為密文
  • 使用 CBC 模式提供更好的安全性
  • 支援 256 位元金鑰長度

2. AES-256 解密

  • 將密文解密為原始明文
  • 需要相同的密碼、Salt 和 IV 才能正確解密

3. 安全特性

  • 使用 PBKDF2WithHmacSHA256 進行金鑰衍生
  • 支援自定義 Salt 值增加安全性
  • 使用安全的 CBC 加密模式
  • 提供 IV(初始化向量)生成功能

使用方法

加密方法

// 基本加密(使用預設金鑰)
String encrypted = Aes256Utils.encryptAES256(plainText);

// 使用自定義金鑰加密
String encrypted = Aes256Utils.encryptAES256(plainText, passwordKey);

// 使用自定義金鑰和 Salt 加密
String encrypted = Aes256Utils.encryptAES256(plainText, passwordKey, salt);

// 完整參數加密
String encrypted = Aes256Utils.encryptAES256(plainText, passwordKey, salt, stringIv);

解密方法

// 基本解密(使用預設金鑰)
String decrypted = Aes256Utils.decryptAES256(encryptedText);

// 使用自定義金鑰解密
String decrypted = Aes256Utils.decryptAES256(encryptedText, passwordKey);

// 使用自定義金鑰和 Salt 解密
String decrypted = Aes256Utils.decryptAES256(encryptedText, passwordKey, salt);

// 完整參數解密
String decrypted = Aes256Utils.decryptAES256(encryptedText, passwordKey, salt, stringIv);

工具方法

// 產生新的 IV
byte[] iv = Aes256Utils.generateAes256ByteIv();

重要注意事項

  1. 環境設定

    • 預設會使用系統環境變數中的金鑰和 IV
    • 需要設定以下環境變數:
      • AES256_PASSWORD_KEY:加密金鑰
      • AES256_IV_KEY:初始化向量
      • AES256_SALT_KEY:Salt 值
  2. 異常處理
    使用時需要處理以下可能的異常:

    • IOException
    • NoSuchAlgorithmException
    • InvalidKeySpecException
    • NoSuchPaddingException
    • InvalidAlgorithmParameterException
    • InvalidKeyException
    • BadPaddingException
    • IllegalBlockSizeException
  3. 安全考量

    • 請妥善保管加密金鑰和 IV
    • 建議定期更換 Salt 和 IV
    • 不要在程式碼中硬編碼金鑰相關資訊

技術規格

  • 加密演算法:AES-256
  • 加密模式:CBC
  • 填充方式:PKCS5Padding
  • 金鑰衍生:PBKDF2WithHmacSHA256
  • IV 長度:16 位元組
  • 金鑰長度:256 位元
  • 迭代次數:65536

單元測試範例

這些測試案例展示了以下功能的正確性:

  • 基本加密解密功能
  • 自定義參數加密解密
  • 異常處理情況
  • IV 生成功能

1. 基本加密解密測試

@Test
void testBasicEncryptDecrypt() {
   String plainText = "Hello, World!";
   // 使用預設金鑰加密
   String encrypted = Aes256Utils.encryptAES256(plainText);
   assertNotNull(encrypted, "加密結果不應為 null");
   assertNotEquals(plainText, encrypted, "加密後的文字不應與原文相同");
    
   // 解密並驗證
   String decrypted = Aes256Utils.decryptAES256(encrypted);
   assertEquals(plainText, decrypted, "解密後應該與原文相同");
}

2. 自定義參數加密解密測試

@Test
void testCustomKeyEncryptDecrypt() {
   String plainText = "測試中文文字";
   String customKey = "MySecretKey123!@#";
   String customSalt = "CustomSalt";
   String customIv = Base64.getEncoder().encodeToString(
      Aes256Utils.generateAes256ByteIv());
    
   // 使用自定義參數加密
   String encrypted = Aes256Utils.encryptAES256(
      plainText, customKey, customSalt, customIv);
   assertNotNull(encrypted, "加密結果不應為 null");
    
   // 使用相同參數解密
   String decrypted = Aes256Utils.decryptAES256(
      encrypted, customKey, customSalt, customIv);
   assertEquals(plainText, decrypted, "使用自定義參數解密後應與原文相同");
    
   // 使用不同金鑰解密(應該失敗)
   assertThrows(Exception.class, () -> {
      Aes256Utils.decryptAES256(encrypted, "WrongKey", customSalt, customIv);
   }, "使用錯誤的金鑰應該拋出異常");
}

3. IV 生成測試

@Test
void testIvGeneration() {
   // 測試 IV 生成
   byte[] iv1 = Aes256Utils.generateAes256ByteIv();
   byte[] iv2 = Aes256Utils.generateAes256ByteIv();
    
   assertNotNull(iv1, "生成的 IV 不應為 null");
   assertEquals(16, iv1.length, "IV 長度應為 16 位元組");
   assertFalse(Arrays.equals(iv1, iv2), "連續生成的 IV 應該不同");
}

4. 異常處理測試

@Test
void testExceptionHandling() {
   String plainText = "Test Data";
    
   // 測試 null 輸入
   assertThrows(IllegalArgumentException.class, () -> {
      Aes256Utils.encryptAES256(null);
   }, "null 輸入應拋出異常");
    
   // 測試空字串輸入
   assertThrows(IllegalArgumentException.class, () -> {
      Aes256Utils.encryptAES256("");
   }, "空字串輸入應拋出異常");
    
   // 測試無效的 Base64 輸入
   assertThrows(IllegalArgumentException.class, () -> {
      Aes256Utils.decryptAES256("InvalidBase64");
   }, "無效的 Base64 輸入應拋出異常");
}

測試案例說明

  1. 基本加密解密測試

    • 驗證使用預設參數的加密解密功能
    • 確認加密後的文字與原文不同
    • 驗證解密後能還原原始文字
  2. 自定義參數加密解密測試

    • 測試使用自定義金鑰、Salt 和 IV
    • 驗證中文文字的處理
    • 測試錯誤金鑰的錯誤處理
  3. IV 生成測試

    • 驗證 IV 的長度符合規格
    • 確認生成的 IV 具有隨機性
    • 測試連續生成的 IV 是否不同
  4. 異常處理測試

    • 驗證各種無效輸入的處理
    • 測試 null 和空字串的處理
    • 確認無效 Base64 的處理

注意事項

  1. 測試環境準備

    • 確保測試環境已設定必要的環境變數
    • 建議使用臨時的測試專用金鑰
    • 避免在測試中使用生產環境的金鑰
  2. 測試資料安全性

    • 測試用的金鑰和 Salt 不應該包含敏感資訊
    • 測試完成後應清理敏感測試資料
    • 確保測試案例不會洩露安全資訊

程式碼 Aes256Utils.java

package tw.lewishome.webapp.base.utility.common;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import tw.lewishome.webapp.GlobalConstants;
/**
 * AES256 加密解密工具類別
 * 此類別提供 AES-256 加密和解密功能,使用 CBC 模式和 PKCS5Padding 填充。
 * 
 * 主要功能:
 * - AES-256 加密:將明文字串加密為密文
 * - AES-256 解密:將密文解密為原始明文
 * - 初始化向量(IV)生成:產生用於加解密的 IV
 * 
 * 安全特性:
 * - 使用 PBKDF2WithHmacSHA256 進行金鑰衍生
 * - 支援自定義 Salt 值增加安全性
 * - 使用 CBC 模式提供更好的安全性
 * - 支援 256 位元金鑰長度
 * 
 * 使用須知:
 * - 此類別為工具類別,所有方法皆為靜態方法
 * - 不允許建立此類別的實例
 * - 加解密過程中需要相同的密碼、Salt 和 IV 才能正確運作
 * - 預設會使用系統環境變數中的金鑰和 IV
 * 
 * 異常處理:
 * - 所有方法都可能拋出加解密相關的異常
 * - 使用時需要適當的異常處理機制
 * 
 * @author Lewis
 * @version 1.0
 */
public class Aes256Utils {

	/** Private constructor to prevent instantiation */
	private Aes256Utils() {
		throw new IllegalStateException("This is a utility class and cannot be instantiated");
	}
    // =================== AES256 Decrypt Method ===================//

	/**
	 * AES256 String 解壓縮(解密) (Default Public Key)
	 *
	 * @param encryptText a String object
	 * @return decryptAES256 String object
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 */
	public static String decryptAES256(String encryptText)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IOException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		String slat = getDefaultSlat();
		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		String passwordKey = GlobalConstants.ENV_VAR.get(GlobalConstants.AES256_PASSWORD_KEY);
		if (StringUtils.isBlank(slat)) {
			Map<String, String> mapKeyParis = RSAUtils.loadKeyParisString();
			passwordKey = mapKeyParis.get(RSAUtils.PUBLIC_KEY);
		} else {
			passwordKey = RSAUtils.decryptStringByPrivateKey(slat);
		}

		return decryptAES256(encryptText, passwordKey, slat, stringIv);
	}

	/**
	 * AES256 String 解壓縮(解密) (Default Public Key)
	 *
	 * @param encryptText a String object
	 * @param passwordKey a String object
	 * @return decryptAES256 String object
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 */
	public static String decryptAES256(String encryptText, String passwordKey)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IOException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		String slat = getDefaultSlat();
		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		return decryptAES256(encryptText, passwordKey, slat, stringIv);
	}

	/**
	 * AES256 String 解壓縮(解密) (Default Public Key)
	 *
	 * @param encryptText a String object
	 * @param passwordKey a String object
	 * @param slat        a String object
	 * @return decryptAES256 String object
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 */
	public static String decryptAES256(String encryptText, String passwordKey, String slat)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IOException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		return decryptAES256(encryptText, passwordKey, slat, stringIv);
	}
    
	/**
	 * AES256 String 解壓縮(解密) (Default Public Key)
	 *
	 * @param encryptText a String object
	 * @param passwordKey a String object
	 * @param slat        a String object
	 * @param stringIv    a String object
	 * @return decryptAES256 String object
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 */	
	public static String decryptAES256(String encryptText, String passwordKey, String slat, String stringIv)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IOException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		byte[] byteIv = TypeConvert.hexStringToBytes(stringIv);		 
		IvParameterSpec ivParameterSpec = new IvParameterSpec(byteIv);

		SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
		KeySpec spec = new PBEKeySpec(passwordKey.toCharArray(), slat.getBytes(), 65536,
				256);
		SecretKey secretKey = factory.generateSecret(spec);
		SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");

		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
		cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
		return (new String(cipher.doFinal(Base64.getDecoder().decode(encryptText))));

	}
    // =================== AES256 Encrypt Method ===================//

	/**
	 * AES256 String 壓縮(加密) (Default Public Key)
	 *
	 * @param plainText a String object
	 * @return encryptAES256 String
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 * 
	 */	public static String encryptAES256(String plainText)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		String slat = getDefaultSlat();
		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		String passwordKey = GlobalConstants.ENV_VAR.get(GlobalConstants.AES256_PASSWORD_KEY);
		if (StringUtils.isBlank(slat)) {
			Map<String, String> mapKeyParis = RSAUtils.loadKeyParisString();
			passwordKey = mapKeyParis.get(RSAUtils.PUBLIC_KEY);
		} else {
			passwordKey = RSAUtils.decryptStringByPrivateKey(slat);
		}
		return encryptAES256(plainText, passwordKey, slat, stringIv);

	}
	/**
	 * AES256 String 壓縮(加密) (Default Public Key)
	 *
	 * @param plainText   a String object
	 * @param passwordKey a String object
	 * @return encryptAES256 String
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 * 
	 */
	public static String encryptAES256(String plainText, String passwordKey)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		String slat = getDefaultSlat();
		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		return encryptAES256(plainText, passwordKey, slat, stringIv);

	}
	/**
	 * AES256 String 壓縮(加密) (Default Public Key)
	 *
	 * @param plainText   plainText String object
	 * @param passwordKey passwordKey String object
	 * @param slat        slat String object
	 * @return encryptAES256 String
	 * 
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 * 
	 */
	public static String encryptAES256(String plainText, String passwordKey, String slat)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		byte[] byteIv = getDefaultByteIv();
		String stringIv = TypeConvert.bytesToHexString(byteIv);
		return encryptAES256(plainText, passwordKey, slat, stringIv);
	}
	/**
	 * AES256 String 壓縮(加密) (Default Public Key)
	 *
	 * @param plainText   plainText String object
	 * @param passwordKey passwordKey String object
	 * @param slat        slat String object
	 * @param stringIv    stringIv String object
	 * @return encryptAES256 String
	 * @throws IOException                        IOException IOException
	 * @throws NoSuchAlgorithmException           NoSuchAlgorithmException
	 * @throws InvalidKeySpecException            InvalidKeySpecException
	 * @throws NoSuchPaddingException             NoSuchPaddingException
	 * @throws InvalidAlgorithmParameterException InvalidAlgorithmParameterException
	 * @throws InvalidKeyException                InvalidKeyException
	 * @throws BadPaddingException                BadPaddingException
	 * @throws IllegalBlockSizeException          IllegalBlockSizeException
	 * 
	 */	
	public static String encryptAES256(String plainText, String passwordKey, String slat, String stringIv)
			throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
			InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

		byte[] byteIv = TypeConvert.hexStringToBytes(stringIv);
		IvParameterSpec ivParameterSpec = new IvParameterSpec(byteIv);
		SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
		KeySpec keySpec = new PBEKeySpec(passwordKey.toCharArray(), slat.getBytes(), 65536,
				256);
		SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
		SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
		return (Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8))));

	}
	/**
	 * 產生 AES256 初始化向量 (IV)
	 * 
	 * @return Byte 初始化向量(IV)
	 */
	public static byte[] generateAes256ByteIv() {
		byte[] iv = new byte[16];
		new SecureRandom().nextBytes(iv);
		return iv;
	}

	/**
	 * 取得預設的 AES256 初始化向量 (IV)
	 * 
	 * @return Byte 初始化向量(IV)
	 */
	private static byte[] getDefaultByteIv() {
		

		String stringIv = GlobalConstants.ENV_VAR.get(GlobalConstants.AES256_IV_KEY);
		if (StringUtils.isBlank(stringIv)) {
			byte[] byteIv = generateAes256ByteIv();
			stringIv = TypeConvert.bytesToHexString(byteIv);
			GlobalConstants.ENV_VAR.put(GlobalConstants.AES256_IV_KEY, stringIv);
		}
		return TypeConvert.hexStringToBytes(stringIv);
	}

	/**
	 * 取得預設的 AES256 Slat
	 * 
	 * @return String default SLAT
	 * @throws IOException
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeySpecException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	private static String getDefaultSlat() throws IOException, InvalidKeyException, NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException {
	
		String slat = GlobalConstants.ENV_VAR.get(GlobalConstants.AES256_SALT_KEY);
		if (StringUtils.isBlank(slat)) {
			Map<String, String> mapKeyParis = RSAUtils.loadKeyParisString();
			slat = mapKeyParis.get(RSAUtils.PUBLIC_KEY);
		} else {
			slat = RSAUtils.decryptStringByPrivateKey(slat);
		}
		return slat;
	}
}

單元測試程式碼 Aes256UtilsTest.java

package tw.lewishome.webapp.base.utility.common;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;

public class Aes256UtilsTest {

    @Test
    public void TestEncryptAES256() {
        try {
            String encString = Aes256Utils.encryptAES256("planText", "PasswordKey");
            System.out.println(encString);            
            String decString = Aes256Utils.decryptAES256(encString, "PasswordKey");
            System.out.println(decString);
            // 驗證解密後的字串是否與原始明文相同
            assertEquals("planText", decString);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Test
    public void testEncryptAES256WithSaltAndIv() {
        try {
            String plainText = "testMessage";
            String password = "testPassword";
            String salt = "testSalt";
            byte[] byteIv = Aes256Utils.generateAes256ByteIv();
            String stringIv = TypeConvert.bytesToHexString(byteIv);
            
            String encrypted = Aes256Utils.encryptAES256(plainText, password, salt, stringIv);
            assertNotNull(encrypted);
            
            String decrypted = Aes256Utils.decryptAES256(encrypted, password, salt, stringIv);
            assertEquals(plainText, decrypted);
        } catch (Exception e) {
            fail("Encryption/decryption should not throw exception: " + e.getMessage());
        }
    }

    @Test
    public void testEncryptAES256WithSalt() {
        try {
            String plainText = "testMessage";
            String password = "testPassword";
            String salt = "testSalt";
            
            String encrypted = Aes256Utils.encryptAES256(plainText, password, salt);
            assertNotNull(encrypted);
            
            String decrypted = Aes256Utils.decryptAES256(encrypted, password, salt);
            assertEquals(plainText, decrypted);
        } catch (Exception e) {
            fail("Encryption/decryption should not throw exception: " + e.getMessage());
        }
    }

    @Test
    public void testGenerateAes256ByteIv() {
        byte[] iv1 = Aes256Utils.generateAes256ByteIv();
        byte[] iv2 = Aes256Utils.generateAes256ByteIv();
        
        assertNotNull(iv1);
        assertNotNull(iv2);
        assertEquals(16, iv1.length);
        assertEquals(16, iv2.length);
        assertFalse(Arrays.equals(iv1, iv2));
    }

    @Test
    void testPrivateConstructor() {
        assertThrows(IllegalAccessException.class, () -> {
            Aes256Utils.class.getDeclaredConstructor().newInstance();
        });
    }
}


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言