java 暗号化¶
暗号化と複合化のサンプルクラス¶
package com.snowsaber.util;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AesCbcUtil {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
/**
* 16進数文字列をバイト配列に変換
*/
private static byte[] hexToBytes(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i+1), 16));
}
return data;
}
/**
* AES-CBC復号化
*
* @param encryptedText Base64エンコードされた暗号化文字列
* @param key 暗号化キー(16進数文字列)
* @param iv 初期化ベクトル(16進数文字列)
* @return 復号化された文字列
*/
public static String decrypt(String encryptedText, String key, String iv) {
try {
byte[] keyBytes = hexToBytes(key);
byte[] ivBytes = hexToBytes(iv);
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException("Decryption failed", e);
}
}
/**
* AES-CBC暗号化
*
* @param plainText 平文
* @param key 暗号化キー(16進数文字列)
* @param iv 初期化ベクトル(16進数文字列)
* @return Base64エンコードされた暗号化文字列
*/
public static String encrypt(String plainText, String key, String iv) {
try {
byte[] keyBytes = hexToBytes(key);
byte[] ivBytes = hexToBytes(iv);
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
throw new RuntimeException("Encryption failed", e);
}
}
}
動作確認用のテストケース
package com.snowsaber.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AesCbcUtilTest {
// 16進数文字列形式のキーとIV(32文字 = 16バイト)
private static final String KEY = "0123456789ABCDEF0123456789ABCDEF";
private static final String IV = "FEDCBA9876543210FEDCBA9876543210";
@Test
void testEncryptAndDecrypt() {
String originalText = "Hello, World!";
// 暗号化
String encrypted = AesCbcUtil.encrypt(originalText, KEY, IV);
assertNotNull(encrypted);
// 復号化
String decrypted = AesCbcUtil.decrypt(encrypted, KEY, IV);
assertEquals(originalText, decrypted);
}
@Test
void testDecryptWithInvalidKey() {
String encrypted = AesCbcUtil.encrypt("Test", KEY, IV);
assertThrows(RuntimeException.class, () -> {
// 不正なキー(16進数形式)
AesCbcUtil.decrypt(encrypted, "00112233445566778899AABBCCDDEEFF", IV);
});
}
}