Skip to content

Instantly share code, notes, and snippets.

@praseodym
Last active June 7, 2021 16:38
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save praseodym/f2499b3e14d872fe5b4a to your computer and use it in GitHub Desktop.
Save praseodym/f2499b3e14d872fe5b4a to your computer and use it in GitHub Desktop.
JDK8 AES-GCM code example
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.Arrays;
public class AESGCMUpdateAAD2 {
// AES-GCM parameters
public static final int AES_KEY_SIZE = 128; // in bits
public static final int GCM_NONCE_LENGTH = 12; // in bytes
public static final int GCM_TAG_LENGTH = 16; // in bytes
public static void main(String[] args) throws Exception {
int testNum = 0; // pass
if (args.length > 0) {
testNum = Integer.parseInt(args[0]);
if (testNum <0 || testNum > 3) {
System.out.println("Usage: java AESGCMUpdateAAD2 [X]");
System.out.println("X can be 0, 1, 2, 3");
System.exit(1);
}
}
byte[] input = "Hello AES-GCM World!".getBytes();
// Initialise random and generate key
SecureRandom random = SecureRandom.getInstanceStrong();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(AES_KEY_SIZE, random);
SecretKey key = keyGen.generateKey();
// Encrypt
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
final byte[] nonce = new byte[GCM_NONCE_LENGTH];
random.nextBytes(nonce);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] aad = "Whatever I like".getBytes();;
cipher.updateAAD(aad);
byte[] cipherText = cipher.doFinal(input);
// Decrypt; nonce is shared implicitly
cipher.init(Cipher.DECRYPT_MODE, key, spec);
// EXPECTED: Uncommenting this will cause an AEADBadTagException when decrypting
// because AAD value is altered
if (testNum == 1) aad[1]++;
cipher.updateAAD(aad);
// EXPECTED: Uncommenting this will cause an AEADBadTagException when decrypting
// because the encrypted data has been altered
if (testNum == 2) cipherText[10]++;
// EXPECTED: Uncommenting this will cause an AEADBadTagException when decrypting
// because the tag has been altered
if (testNum == 3) cipherText[cipherText.length - 2]++;
try {
byte[] plainText = cipher.doFinal(cipherText);
if (testNum != 0) {
System.out.println("Test Failed: expected AEADBadTagException not thrown");
} else {
// check if the decryption result matches
if (Arrays.equals(input, plainText)) {
System.out.println("Test Passed: match!");
} else {
System.out.println("Test Failed: result mismatch!");
System.out.println(new String(plainText));
}
}
} catch(AEADBadTagException ex) {
if (testNum == 0) {
System.out.println("Test Failed: unexpected ex " + ex);
ex.printStackTrace();
} else {
System.out.println("Test Passed: expected ex " + ex);
}
}
}
}
@bsreera
Copy link

bsreera commented Oct 10, 2016

With the default JDK8 implementation is it necessary to provide the tag length? I think the default itself is 128 bytes and the same is being provided here as well.

@thomasrichner-oviva
Copy link

For completeness you should also add the IV to the tag, e.g. cipher.updateAAD(nonce);

@Tomato-
Copy link

Tomato- commented Apr 16, 2018

How to alter key size from 128 to 256? cannot only alter param AES_KEY_SIZE to 256
Thanks!

I know the reason now: https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters

Copy link

ghost commented Jun 26, 2019

This code throws a error
java.security.InvalidAlgorithmParameterException: unknown parameter type.
while running the same on JDK 12

@cinderblocks
Copy link

For completeness you should also add the IV to the tag, e.g. cipher.updateAAD(nonce);

The nonce is already included in the calculation of the authentication tag. Not really any reason why you would need to include it in AAD as you can't verify it without already having the IV in the first place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment