2
$\begingroup$

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

$\endgroup$

1 Answer 1

2
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.