Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get authentication tag from AES-GCM

I'm using BouncyCastle to encrypt data in C#, using the AES256 GCM algorithm. For this I'm using the implementation provided by James Tuley. Below is a snippet of this code:

public byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
{
    if (key == null || key.Length != KeyBitSize / 8)
        throw new ArgumentException($"Key needs to be {KeyBitSize} bit!", nameof(key));

    if (secretMessage == null || secretMessage.Length == 0)
        throw new ArgumentException("Secret Message Required!", nameof(secretMessage));

    nonSecretPayload = nonSecretPayload ?? new byte[] { };
        
    byte[] nonce = _csprng.RandomBytes(NonceBitSize / 8);

    var cipher = new GcmBlockCipher(new AesFastEngine());
    var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
    cipher.Init(true, parameters);
        
    var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
    int len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);
    cipher.DoFinal(cipherText, len);
        
    using (var combinedStream = new MemoryStream())
    {
        using (var binaryWriter = new BinaryWriter(combinedStream))
        {
            binaryWriter.Write(nonSecretPayload);
            binaryWriter.Write(nonce);
            binaryWriter.Write(cipherText);
        }

        return combinedStream.ToArray();
    }
}

I need to get the authentication tag (mentioned in RFC 5084). It mentions that the authentication tag is part of the output:

AES-GCM generates two outputs: a ciphertext and message authentication code (also called an authentication tag).

I don't understand though how to get the authentication tag from this code? Can anyone help me out?

like image 707
Leon Cullens Avatar asked Nov 25 '25 22:11

Leon Cullens


1 Answers

Call the GetMac() function of the cipher object to obtain the authentication tag:

...
cipher.DoFinal(cipherText, len);
var auth_tag =  cipher.GetMac();
...

Source: http://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/modes/GCMBlockCipher.html "Return the value of the MAC associated with the last stream processed" MAC = "Message Authentication Code"

The documentation of the DoFinal() function states "Finish the operation either appending or verifying the MAC at the end of the data", which seems to confirm the earlier hypothesis that the cipherText will already contain the MAC, too. Using GetMacSize(), you should be able to determine its offset from the end of the cipherText.

like image 133
Cee McSharpface Avatar answered Nov 28 '25 11:11

Cee McSharpface



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!