Skip to content

Instantly share code, notes, and snippets.

@DuncanCasteleyn
Last active December 20, 2022 20:28
Show Gist options
  • Save DuncanCasteleyn/7c7099b9631e55c0b39770c42182c2b4 to your computer and use it in GitHub Desktop.
Save DuncanCasteleyn/7c7099b9631e55c0b39770c42182c2b4 to your computer and use it in GitHub Desktop.
AES GCM String Encrypt and decrypt component for Spring
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
@Component
public class AESGCMEncryptDecrypt {
private static final int KEY_SIZE = 128; // in bits
private static final int GCM_IV_LENGTH = 12; // in bytes
private static final int GCM_TAG_LENGTH = 16; // in bytes
private static final String SECRET_KEY_FACTORY_ALGORITHM = "PBKDF2WithHmacSHA256";
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
public byte[] encrypt(String password, String salt, String plaintext) throws Exception {
// Generate a secure random IV
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[GCM_IV_LENGTH];
secureRandom.nextBytes(iv);
// Generate the secret key using PBKDF2
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 10000, KEY_SIZE);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Encrypt the plaintext using AES GCM
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
// Concatenate the IV and ciphertext
ByteBuffer buffer = ByteBuffer.allocate(GCM_IV_LENGTH + ciphertext.length);
buffer.put(iv);
buffer.put(ciphertext);
byte[] encrypted = buffer.array();
return encrypted;
}
public String decrypt(String password, String salt, byte[] encrypted) throws Exception {
// Split the IV and ciphertext
ByteBuffer buffer = ByteBuffer.wrap(encrypted);
byte[] iv = new byte[GCM_IV_LENGTH];
buffer.get(iv);
byte[] ciphertext = new byte[encrypted.length - GCM_IV_LENGTH];
buffer.get(ciphertext);
// Generate the secret key using PBKDF2
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 10000, KEY_SIZE);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the ciphertext using AES GCM
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
byte[] plaintext = cipher.doFinal(ciphertext);
return new String(plaintext);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment