Search code examples
javaaesaes-gcm

Checking tag and associated data in an AEAD cipher in Java


I need to use AEAD to share information between two users, part of which must be encrypted and part of which should be kept in cleartext.

Is there an API to check the ciphertext tag and access the associated data once a message has been encrypted with AES/GCM ?

In more detail:

I'm using Java 7 with bouncycastle as a provider and I have managed to encrypt and decrypt my data successfully, using the corresponding API:

private byte[] encrypt(SecretKey key, byte[] nonce, byte[] message, byte[] associatedData) throws ... {
   Cipher aeadCipher = Cipher.getInstance(AES_GCM_NOPADDING);
   aeadCipher.init(Cipher.ENCRYPT_MODE, kint, new GCMParameterSpec(GCM_MAC_SIZE, nonce);
   aeadCipher.updateAAD(associatedData);
   return aeadCipher.doFinal(message);
}

private byte[] decrypt(SecretKey key, byte[] nonce, byte[] cipherText, byte[] associatedData) throws ... {
   Cipher aeadCipher = Cipher.getInstance(AES_GCM_NOPADDING);
   aeadCipher.init(Cipher.DECRYPT_MODE, kint, new GCMParameterSpec(GCM_MAC_SIZE, nonce);
   aeadCipher.updateAAD(associatedData);
   return aeadCipher.doFinal(cipherText);
}

However, it is my understanding that AES/GCM ciphertexts should already contain the parameters that could affect decryption (nonce and associatedData). Therefore, I would like to be able to retrieve them from the ciphertext, rather than having to store them alongside the ciphertext and pass them along to the decryption function. Furthermore, I'd like to be able to run integrity checks (computing the tag) and run some checks on the associated data without having to completely decrypt the message.

Is there an API that would allow this and that I might have missed ?

So far, I've checked:


Solution

  • There is no implicit format that stores all the input data of GCM in a specific location. The Java API is already a bit strange in the sense that it automatically places the tag at the end. This makes the algorithm more compatible with the Cipher class, but in principle the tag just needs to be kept with the ciphertext - where does not matter. Now you have the issue that you don't know where the AAD ends and the ciphertext starts for instance.

    So what you can do is either to create your own format (maybe your AAD has a static size, so you can just concatenate) or you can use a predefined container format. There is an internet draft that specifies how to use both modes in the Cryptographic Message Syntax (CMS). The AAD can then be stored in authenticated atributes, which should also include the required parameters (including the IV comprising of the nonce).

    If you feel masochistic you could also try and use XML-encryption with GCM mode, but beware of the many pitfalls with regard to verifying XML authenticity (e.g. beware that you are actually verifying the data you are going to use).

    Bouncy Castle seems to offer support for CMS using GCM.