先日作ったOpenSSLでのaes-ccmの暗号化結果が正しいのか?OpenSSLで復号化して検証してもなんだかなぁ。と思ったのでJavaで検証してみた。
普通にJavaをインストールした状態のjceではaes-ccmはサポートされていない。そんな時はBouncyCastleだ。
package aesccm;
import java.util.HexFormat;
import java.crypto.Cipher;
import java.crypto.IvParameterSpec;
import java.crypto.SecretKeySpec;
import org.bouncycastle.jcajce.spec.AEADParameterSpec;
class App {
private static byte[] keyBytes = {(略)};
private static byte[] ivBytes = {(略)};
private static byte[] plainDataBytes = {(略)};
private static byte[] encryptDataBytes = {(略)};
private static byte[] encryptDataWithTagBytes = {(略)};
public static void main( String[] args) {
try {
java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
catch( Exception e) {
e.printStackTrace();
return;
}
var hex = HexFormat.ofDelimiter( ", ").withPrefix( "0x");
var encryptData = encrypt( plainDataBytes);
System.out.println( encryptData);
var encryptFreeTagSizeData = encryptFreeTagSize( plainDataBytes);
System.out.println( encryptFreeTagSizeData);
var decryptData = decrypt( encryptDataBytes);
System.out.println( decryptData);
var decryptFreeTagSizeData = decryptFreeTagSize( encryptDataWithTagBytes);
System.out.println( decryptFreeTagSizeData);
}
public static byte[] encrypt( byte[] dataBytes) {
// rfc 規定の方法で暗号化 Tag は暗号化データと連結される
try{
var ciper = Cipher.getInstance( "AES/CCM/NoPadding");
var key = new SecretKeySpec( keyBytes, "AES");
var iv = new IvParameterSpec( ivBytes);
cipher.init( Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal( dataBytes);
}
catch( Exception e) {
e.printStackTrace();
}
return new byte[0];
}
public static byte[] encryptFreeTagSize( byte[] dataBytes) {
// Tag のサイズを指定した暗号化
try{
var ciper = Cipher.getInstance( "AES/CCM/NoPadding");
var key = new SecretKeySpec( keyBytes, "AES");
// Tag のサイズは "bit"数 で指定する。ゼロを指定するとタグは付かない
var aeadParameterSpec = new AEADParameterSpec( ivBytes, 32);
cipher.init( Cipher.ENCRYPT_MODE, key, aeadParameterSpec);
return cipher.doFinal( dataBytes);
}
catch( Exception e) {
e.printStackTrace();
}
return new byte[0];
}
public static byte[] decrypt( byte[] dataBytes) {
// rfc 規定の方法で暗号化 されたデータの復号化
try{
var ciper = Cipher.getInstance( "AES/CCM/NoPadding");
var key = new SecretKeySpec( keyBytes, "AES");
var iv = new IvParameterSpec( ivBytes);
cipher.init( Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal( dataBytes);
}
catch( Exception e) {
e.printStackTrace();
}
return new byte[0];
}
public static byte[] decryptFreeTagSize( byte[] dataBytes) {
// rfc 規定の方法で暗号化 されたデータの復号化
try{
var ciper = Cipher.getInstance( "AES/CCM/NoPadding");
var key = new SecretKeySpec( keyBytes, "AES");
// Tag のサイズは "bit"数 で指定する。ゼロを指定するとタグの検証は行われない
var aeadParameterSpec = new AEADParameterSpec( ivBytes, 32);
cipher.init( Cipher.DECRYPT_MODE, key, aeadParameterSpec);
return cipher.doFinal( dataBytes);
}
catch( Exception e) {
e.printStackTrace();
}
return new byte[0];
}
}