I am pretty new to cryptography and have a sample of GCM mode of operation for AES.
PFB the code

    Cipher c = Cipher.getInstance ("AES/GCM/NoPadding");
    final int blockSize = 96;//c.getBlockSize();
    final byte[] ivData = new byte[blockSize];
    System.out.println("IV :- "+new String(ivData) );
    final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
    System.out.println("IV :- "+new String(ivData) );
    GCMParameterSpec params = new GCMParameterSpec(blockSize , ivData);
    SecureRandom sr = new SecureRandom();
    byte[] aesKey = MessageDigest.getInstance("MD5").digest(
    byte[] ciphertext;
    byte[] head = "Header information".getBytes();
    byte[] data = "Data to encrypt".getBytes();
    SecretKeySpec sks = new SecretKeySpec(aesKey, "AES");
    c.init(Cipher.ENCRYPT_MODE, sks, params);
    ciphertext = c.doFinal(data);
    System.out.println("done   "+ new String(ciphertext));

    c.init(Cipher.DECRYPT_MODE, sks, params);

    ciphertext = c.doFinal(ciphertext);
    System.out.println("done   "+ new String(ciphertext));

But I need to do Authentication using GMAC. How do I do authentication using GMAC without encrypting/decrypting? Any pointers or suggestions will be very helpful.

  • $\begingroup$ How about passing empty data to c.doFinal(data); ? $\endgroup$ – Dmitry Janushkevich Jul 16 '14 at 13:51
  • $\begingroup$ But how do i specify to use GMAC.Will it be used automactically $\endgroup$ – Manu Jul 16 '14 at 13:59
  • 1
    $\begingroup$ Yes. GCM assumes GMAC, if I understand this correctly. Too bad official docs don't say much on this. $\endgroup$ – Dmitry Janushkevich Jul 16 '14 at 14:25
  • 1
    $\begingroup$ GMAC is just GCM with a empty "message to be encrypted" $\endgroup$ – poncho Jul 16 '14 at 14:30
  • 2
    $\begingroup$ The "additional associated data"; that's the part of the data which is used to compute the tag, but is not encrypted. $\endgroup$ – poncho Jul 16 '14 at 15:02

GMAC is quite simply GCM mode where all data is supplied as AAD (or additional authenticated data), or as NIST SP 800-38D puts it:

If the GCM input is restricted to data that is not to be encrypted, the resulting specialization of GCM, called GMAC, is simply an authentication mode on the input data.

If you don't have access to a cryptographic provider that supports GMAC directly (e.g. Bouncy Castle provides a AES-GMAC JCE Mac) you can simply use any AES/GCM implementation by providing all data as AAD, and an empty message for encryption.

e.g. adapting your example to do GMAC only:

... as for AES/GCM ...
byte[] mac = c.doFinal();
System.out.println("GMAC: " + SomeHexEncoder.encode(mac));

If you need to be certain you're getting it right, the GCM/GMAC test vectors from the NIST CAVP page can be used (everything with a PTlen = 0 is a GMAC test vector).

| improve this answer | |

You can supply all your data as aad and keep the plain text with 0 length. Below code is in c# using bounty castle library. If the data is null, it will just generate the authentication tag without encrypting.

public static class Security
    public static byte[] GCMEncrypt(byte[] data, byte[] key, byte[] iv, byte[] aad, out byte[] authTag)
        authTag = new byte[12];
        //Non-secret Payload Optional
        aad = aad ?? new byte[] { };

        var cipher = new GcmBlockCipher(new AesFastEngine());
        var parameters = new AeadParameters(new KeyParameter(key), 96, iv, aad);
        cipher.Init(true, parameters);
        if(data == null)

            var cipherText1 = new byte[cipher.GetOutputSize(0)];
            cipher.DoFinal(cipherText1, 0);
            authTag = cipherText1;
            return authTag;

        //Generate Cipher Text With Auth Tag
        var cipherText = new byte[cipher.GetOutputSize(data.Length)];
        var len = cipher.ProcessBytes(data, 0, data.Length, cipherText, 0);
        cipher.DoFinal(cipherText, len);

        byte[] ret = new byte[data.Length];

        Array.Copy(cipherText, ret, data.Length);
        if(cipherText.Length > data.Length)
            Array.Copy(cipherText, data.Length, authTag, 0, cipherText.Length - data.Length);

        return ret;
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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