com.akeyless.crypto.aes.gcm.GCMHandler Maven / Gradle / Ivy
package com.akeyless.crypto.aes.gcm;
import com.akeyless.crypto.utils.SecureRandomGen;
import com.akeyless.exceptions.AkeylessCryptoException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
public class GCMHandler {
private final static int GCM_TAG_LENGTH = 16;
private final static int GCM_NONCE_LENGTH = 12;
private final static int GCM_TAG_LENGTH_BITS = GCM_TAG_LENGTH * 8;
private SecretKeySpec aesKey = null;
public GCMHandler(byte[] key) {
aesKey = new SecretKeySpec(key, "AES");
}
public byte[] encrypt(byte[] data) throws InvalidKeyException, AkeylessCryptoException {
return encrypt(data, null);
}
public byte[] encrypt(byte[] data, byte[] aad) throws InvalidKeyException, AkeylessCryptoException {
SecureRandom s = SecureRandomGen.get();
byte[] nonce = new byte[GCM_NONCE_LENGTH];
s.nextBytes(nonce);
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH_BITS, nonce);
try {
Cipher gcmCipher = Cipher.getInstance("AES/GCM/NoPadding");
gcmCipher.init(Cipher.ENCRYPT_MODE, aesKey, gcmSpec);
if (aad != null) {
gcmCipher.updateAAD(aad);
}
byte[] encryptedData = gcmCipher.doFinal(data);
ByteBuffer bb = ByteBuffer.allocate(nonce.length+encryptedData.length);
bb.put(nonce);
bb.put(encryptedData);
return bb.array();
} catch (NoSuchAlgorithmException |
NoSuchPaddingException |
InvalidAlgorithmParameterException |
BadPaddingException |
IllegalBlockSizeException e) {
throw new AkeylessCryptoException(e);
}
}
public byte[] decrypt(byte[] data) throws InvalidKeyException, AkeylessCryptoException {
return decrypt(data, null);
}
public byte[] decrypt(byte[] cipher, byte[] aad) throws InvalidKeyException, AkeylessCryptoException {
byte[] nonce = extractNonceFromCipher(cipher);
byte[] encryptedData = extractEncryptedDataFromCipher(cipher);
GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH_BITS, nonce);
try {
Cipher gcmCipher = Cipher.getInstance("AES/GCM/NoPadding");
gcmCipher.init(Cipher.DECRYPT_MODE, aesKey, gcmSpec);
if (aad != null) {
gcmCipher.updateAAD(aad);
}
return gcmCipher.doFinal(encryptedData);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException |
InvalidAlgorithmParameterException |
BadPaddingException |
IllegalBlockSizeException e) {
throw new AkeylessCryptoException(e);
}
}
private static byte[] extractNonceFromCipher(byte[] cipher) {
return Arrays.copyOfRange(cipher, 0, GCM_NONCE_LENGTH);
}
private static byte[] extractEncryptedDataFromCipher(byte[] cipher) {
return Arrays.copyOfRange(cipher, GCM_NONCE_LENGTH, cipher.length);
}
}