先日作った 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) {
        // 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.DECRYPT_MODE, key, aeadParameterSpec);
            return cipher.doFinal( dataBytes);
        }
        catch( Exception e) {
            e.printStackTrace();
        }
        return new byte[0];
    }
}
 
0 件のコメント:
コメントを投稿