All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.akeyless.crypto.aes.gcm.GCMHandler Maven / Gradle / Ivy

There is a newer version: 0.0.10
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy