0

How can one use cipher.updateAAD() below API 19 (Java 7)? I know I can use BouncyCastle but it does not provide a backport for AEAD encryption and decryption. Are there any third-party libraries? I am using AES/GCM/NoPadding.

gi097
  • 7,313
  • 3
  • 27
  • 49

2 Answers2

1

Actually BouncyCastle offers all the things I needed, including AAD. For AES/GCM we can use these methods:

    static byte[] gcmDecrypt(byte[] ct, byte[] key, byte[] iv, byte[] aad) throws Exception {
        AEADParameters parameters = new AEADParameters(new KeyParameter(key), 128, iv, aad);
        GCMBlockCipher gcmEngine = new GCMBlockCipher(new AESFastEngine());
        gcmEngine.init(false, parameters);
        byte[] pt = new byte[gcmEngine.getOutputSize(ct.length)];
        int len = gcmEngine.processBytes(ct, 0, ct.length, pt, 0);
        gcmEngine.doFinal(pt, len);
        return pt;
    }

    static byte[] gcmEncrypt(byte[] pt, byte[] key, byte[] iv, byte[] aad) throws Exception {
        AEADParameters parameters = new AEADParameters(new KeyParameter(key), 128, iv, aad);
        GCMBlockCipher gcmEngine = new GCMBlockCipher(new AESFastEngine());
        gcmEngine.init(true, parameters);
        byte[] ct = new byte[gcmEngine.getOutputSize(pt.length)];
        int len = gcmEngine.processBytes(pt, 0, pt.length, ct, 0);
        gcmEngine.doFinal(ct, len);
        return ct;
    }
gi097
  • 7,313
  • 3
  • 27
  • 49
0

I improved the encrypt code above and tested it on a Sony Android 4.3 phone

    import javax.crypto.Cipher;
    import javax.crypto.Mac;
    import javax.crypto.spec.GCMParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.bouncycastle.crypto.engines.AESEngine;
    import org.bouncycastle.crypto.modes.GCMBlockCipher;
    import org.bouncycastle.crypto.params.AEADParameters;
    import org.bouncycastle.crypto.params.KeyParameter;
        
    
    public static byte[] encrypt(byte[] password, byte[] key, byte[] iv, byte[] aad) throws Exception {
        byte[] encrypt;
        if (Build.VERSION.SDK_INT >= 21) {
            cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(128, iv));
            cipher.updateAAD(aad);
            encrypt = cipher.doFinal(password);
        } else {
            AEADParameters aeadParameters = new AEADParameters(new KeyParameter(key), 128, iv, aad);
            GCMBlockCipher gcmBlockCipher = new GCMBlockCipher(new AESEngine());
            gcmBlockCipher.init(true, aeadParameters);
            //gcmEngine.processAADBytes(aad, 0, aad.length);//-- if use this remove aad in constructor AEADParameters
        
            encrypt = new byte[gcmBlockCipher.getOutputSize(password.length)];
            int length = gcmBlockCipher.processBytes(password, 0, password.length, encrypt, 0);
            gcmBlockCipher.doFinal(encrypt, length);
        }
        Log.e("encrypted : " + Arrays.toString(encrypt));
        return encrypt;
    }

  dependencies {
        //-- https://www.bouncycastle.org/latest_releases.html
        //implementation 'org.bouncycastle:bcpkix-jdk15to18:1.68'
        implementation 'org.bouncycastle:bcprov-jdk15to18:1.68'
    }

thanks @gi097, https://stackoverflow.com/a/62924766/6356601

Saeed
  • 1
  • 1
  • 1