Skip to content

Instantly share code, notes, and snippets.

@chanchal-357
Last active October 2, 2024 13:39
Show Gist options
  • Save chanchal-357/8c84adf7255d9a349c46be0b2fa508af to your computer and use it in GitHub Desktop.
Save chanchal-357/8c84adf7255d9a349c46be0b2fa508af to your computer and use it in GitHub Desktop.
Java code implementing AES-GCM cryptography, using random IV and salt
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
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.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
public class CryptoUtilAesGcm {
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final String FACTORY_INSTANCE = "PBKDF2WithHmacSHA256";
private static final int TAG_LENGTH_BIT = 128;
private static final int IV_LENGTH_BYTE = 12;
private static final int SALT_LENGTH_BYTE = 16;
private static final String ALGORITHM_TYPE = "AES";
private static final int KEY_LENGTH = 256;
private static final int ITERATION_COUNT = 65536;
private static final Charset UTF_8 = StandardCharsets.UTF_8;
public static byte[] getRandomNonce(int length) {
byte[] nonce = new byte[length];
new SecureRandom().nextBytes(nonce);
return nonce;
}
public static SecretKey getSecretKey(String password, byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);
SecretKeyFactory factory = SecretKeyFactory.getInstance(FACTORY_INSTANCE);
return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), ALGORITHM_TYPE);
}
public static String encrypt(String password, String plainMessage) throws Exception {
byte[] salt = getRandomNonce(SALT_LENGTH_BYTE);
SecretKey secretKey = getSecretKey(password, salt);
// GCM recommends 12 bytes iv
byte[] iv = getRandomNonce(IV_LENGTH_BYTE);
Cipher cipher = initCipher(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] encryptedMessageByte = cipher.doFinal(plainMessage.getBytes(UTF_8));
// prefix IV and Salt to cipher text
byte[] cipherByte = ByteBuffer.allocate(iv.length + salt.length + encryptedMessageByte.length)
.put(iv)
.put(salt)
.put(encryptedMessageByte)
.array();
return Base64.getEncoder().encodeToString(cipherByte);
}
public static String decrypt(String password, String cipherMessage) throws Exception {
byte[] decodedCipherByte = Base64.getDecoder().decode(cipherMessage.getBytes(UTF_8));
ByteBuffer byteBuffer = ByteBuffer.wrap(decodedCipherByte);
byte[] iv = new byte[IV_LENGTH_BYTE];
byteBuffer.get(iv);
byte[] salt = new byte[SALT_LENGTH_BYTE];
byteBuffer.get(salt);
byte[] encryptedByte = new byte[byteBuffer.remaining()];
byteBuffer.get(encryptedByte);
SecretKey secretKey = getSecretKey(password, salt);
Cipher cipher = initCipher(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedMessageByte = cipher.doFinal(encryptedByte);
return new String(decryptedMessageByte, UTF_8);
}
private static Cipher initCipher(int mode, SecretKey secretKey, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchPaddingException, NoSuchAlgorithmException {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(mode, secretKey, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
return cipher;
}
public static void main(String[] args) throws Exception {
String outputFormat = "%-25s:%s%n";
String password = "yourSecretKey";
String message = "M0993000353";
String cipherText = encrypt(password, message);
System.out.println("------ AES-GCM Encryption ------");
System.out.printf(outputFormat, "encryption input", message);
System.out.printf(outputFormat, "encryption output", cipherText);
String decryptedText = decrypt(password, cipherText);
System.out.println("\n------ AES-GCM Decryption ------");
System.out.printf(outputFormat, "decryption input", cipherText);
System.out.printf(outputFormat, "decryption output", decryptedText);
}
}
@OpenSrcerer
Copy link

very useful thank you!

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