Score:2

Validating AES GCM authentication tag between two different implementations

nl flag

I'm a bit confused on how to validate the authentication tag between two different AES GCM implementations.

One implementation (on my part) is in Java. The other, I don't know.

In my implementation, the plaintext is encrypted with the doFinal function. I prepend the initialization vector to the result.

I understand that the authentication tag is added to the end of the encrypted message, and when decrypting it, Java checks it automatically.

https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html If an AEAD mode such as GCM/CCM is being used, the authentication tag is appended in the case of encryption, or verified in the case of decryption.

Data

IV: b943f312250e7fb1f29dea93
Ciphertext (128 bit tag appended): 3745a778189b041b9c452359066a9a745715f214599d010790ee8866e531d5bfe6352e
Key: e08ef62a4908460742b4f80b14fb452d

My question is: Should they be able to verify the tag from the other party, regardless of the crypto implementation/provider they use?

Thank you

Score:2
in flag

Yes, the authentication tag is specified fully in the GCM specifications. Where it is placed is otherwise inconsequential - the location doesn't influence the values of the bits of the authentication tag.

If the other algorithm implementation separates the authentication tag handling - as it probably should - then this should be takeninto consideration during encryption and decryption.

  • To comply with the Java implementation it is required to append the tag to the ciphertext after encryption. Usually it is possible to smartly size a buffer or use a streaming implementation so that copying the tag is not necessary.

  • For verification it may be required to extract it from the tail of ciphertext. Usually it is possible to simply indicate it within the buffer holding the ciphertext though; in that case no copying or resizing is required.


It is required that the GCM configuration parameters (IV/nonce type and size, authentication tag size) are agreed upon in advance by both parties, either by specifying them directly in the protocol, or by choosing a pre-defined set of configuration parameters during runtime.

That means that the authentication tag size should be known in advance. So it should be possible to find the authentication tag once the ciphertext size has been established. Of course, nothing prevents you to include the ciphertext size within the protocol either; it is fine to include, say, a 32 bit size indicator (usually an unsigned 32 bit big endian value) in the header of your protocol. That way it is possible to find the authentication tag without having the entire ciphertext / plaintext within system memory - assuming that the implementation doesn't require the user to perform the encryption / decryption all at once.

Obviously both parties also need to use the same additional authenticated data (AAD) for the tag to verify.


Usually it is recommended to keep the authentication tag to the maximum size of 128 bits (the block size of the AES algorithm and the size of the Galois field of GHASH). The Oracle Java implementation does default to that size. So in that case the last 16 bytes of the (extended) ciphertext make up the authentication tag.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.