Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Java Authenticated Encryption with AES and GCM
package at.favre.lib.bytes.otherPackage;
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import static org.junit.Assert.assertEquals;
/**
* A simple showcase for encryption and decryption with AES + GCM in Java
*/
public class AesGcmTest {
private final SecureRandom secureRandom = new SecureRandom();
private final static int GCM_IV_LENGTH = 12;
@Test
public void testEncryption() throws Exception {
//create new random key
byte[] key = new byte[16];
secureRandom.nextBytes(key);
SecretKey secretKey = new SecretKeySpec(key, "AES");
byte[] associatedData = "ProtocolVersion1".getBytes(StandardCharsets.UTF_8); //meta data you want to verify with the secret message
String message = "the secret message";
byte[] cipherText = encrypt(message, secretKey, associatedData);
String decrypted = decrypt(cipherText, secretKey, associatedData);
assertEquals(message, decrypted);
}
/**
* Encrypt a plaintext with given key.
*
* @param plaintext to encrypt (utf-8 encoding will be used)
* @param secretKey to encrypt, must be AES type, see {@link SecretKeySpec}
* @param associatedData optional, additional (public) data to verify on decryption with GCM auth tag
* @return encrypted message
* @throws Exception if anything goes wrong
*/
private byte[] encrypt(String plaintext, SecretKey secretKey, byte[] associatedData) throws Exception {
byte[] iv = new byte[GCM_IV_LENGTH]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
if (associatedData != null) {
cipher.updateAAD(associatedData);
}
byte[] cipherText = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
byteBuffer.put(iv);
byteBuffer.put(cipherText);
return byteBuffer.array();
}
/**
* Decrypts encrypted message (see {@link #encrypt(String, SecretKey, byte[])}).
*
* @param cipherMessage iv with ciphertext
* @param secretKey used to decrypt
* @param associatedData optional, additional (public) data to verify on decryption with GCM auth tag
* @return original plaintext
* @throws Exception if anything goes wrong
*/
private String decrypt(byte[] cipherMessage, SecretKey secretKey, byte[] associatedData) throws Exception {
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, GCM_IV_LENGTH);
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmIv);
if (associatedData != null) {
cipher.updateAAD(associatedData);
}
//use everything from 12 bytes on as ciphertext
byte[] plainText = cipher.doFinal(cipherMessage, GCM_IV_LENGTH, cipherMessage.length - GCM_IV_LENGTH);
return new String(plainText, StandardCharsets.UTF_8);
}
}
@syedkhizarulhaq-cis
Copy link

syedkhizarulhaq-cis commented Jun 22, 2022

Where is the main file for this class file?

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