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

com.ulisesbocchio.jasyptspringboot.encryptor.SimpleGCMByteEncryptor Maven / Gradle / Ivy

The newest version!
package com.ulisesbocchio.jasyptspringboot.encryptor;

import com.ulisesbocchio.jasyptspringboot.util.Singleton;
import lombok.SneakyThrows;
import org.jasypt.encryption.ByteEncryptor;
import org.jasypt.iv.IvGenerator;
import org.jasypt.salt.SaltGenerator;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
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;
import java.security.spec.KeySpec;
import java.util.Base64;

/**
 * 

SimpleGCMByteEncryptor class.

* * @author Sergio.U.Bocchio * @version $Id: $Id */ public class SimpleGCMByteEncryptor implements ByteEncryptor { /** Constant AES_KEY_SIZE=256 */ public static final int AES_KEY_SIZE = 256; /** Constant AES_KEY_PASSWORD_SALT_LENGTH=16 */ public static final int AES_KEY_PASSWORD_SALT_LENGTH = 16; /** Constant GCM_IV_LENGTH=12 */ public static final int GCM_IV_LENGTH = 12; /** Constant GCM_TAG_LENGTH=128 */ public static final int GCM_TAG_LENGTH = 128; private final Singleton key; private final String algorithm; private final Singleton ivGenerator; /** {@inheritDoc} */ @SneakyThrows @Override public byte[] encrypt(byte[] message) { byte[] iv = this.ivGenerator.get().generateIv(GCM_IV_LENGTH); Cipher cipher = Cipher.getInstance(this.algorithm); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); cipher.init(Cipher.ENCRYPT_MODE, key.get(), gcmParameterSpec); byte[] cipherText = cipher.doFinal(message); ByteBuffer byteBuffer = ByteBuffer.allocate(GCM_IV_LENGTH + cipherText.length); byteBuffer.put(iv); byteBuffer.put(cipherText); return byteBuffer.array(); } /** {@inheritDoc} */ @SneakyThrows @Override public byte[] decrypt(byte[] encryptedMessage) { Cipher cipher = Cipher.getInstance(this.algorithm); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, encryptedMessage, 0, GCM_IV_LENGTH); cipher.init(Cipher.DECRYPT_MODE, key.get(), gcmParameterSpec); return cipher.doFinal(encryptedMessage, GCM_IV_LENGTH, encryptedMessage.length - GCM_IV_LENGTH); } @SneakyThrows private SecretKey loadSecretKey(SimpleGCMConfig config) { if (config.getActualKey() != null) { return config.getActualKey(); } else if (config.getSecretKeyPassword() != null) { Assert.notNull(config.getSecretKeySaltGenerator(), "Secret key Salt must be provided with password"); Assert.notNull(config.getSecretKeyAlgorithm(), "Secret key algorithm must be provided with password"); return getAESKeyFromPassword(config.getSecretKeyPasswordChars(), config.getSecretKeySaltGenerator(), config.getSecretKeyIterations(), config.getSecretKeyAlgorithm()); } else { Assert.state(config.getSecretKey() != null || config.getSecretKeyResource() != null || config.getSecretKeyLocation() != null, "No key provided"); return loadSecretKeyFromResource(config.loadSecretKeyResource()); } } @SneakyThrows private byte[] getResourceBytes(Resource resource) { return FileCopyUtils.copyToByteArray(resource.getInputStream()); } @SneakyThrows private SecretKey loadSecretKeyFromResource(Resource resource) { byte[] secretKeyBytes = Base64.getDecoder().decode(getResourceBytes(resource)); return new SecretKeySpec(secretKeyBytes, "AES"); } /** *

generateSecretKey.

* * @return a {@link javax.crypto.SecretKey} object */ @SneakyThrows public static SecretKey generateSecretKey() { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); SecureRandom random = SecureRandom.getInstanceStrong(); keyGenerator.init(AES_KEY_SIZE, random); return keyGenerator.generateKey(); } /** *

generateBase64EncodedSecretKey.

* * @return a {@link java.lang.String} object */ @SneakyThrows public static String generateBase64EncodedSecretKey() { SecretKey key = generateSecretKey(); byte[] secretKeyBytes = key.getEncoded(); return Base64.getEncoder().encodeToString(secretKeyBytes); } /** *

getAESKeyFromPassword.

* * @param password an array of {@link char} objects * @param saltGenerator a {@link org.jasypt.salt.SaltGenerator} object * @param iterations a int * @param algorithm a {@link java.lang.String} object * @return a {@link javax.crypto.SecretKey} object */ @SneakyThrows public static SecretKey getAESKeyFromPassword(char[] password, SaltGenerator saltGenerator, int iterations, String algorithm){ SecretKeyFactory factory = SecretKeyFactory.getInstance(algorithm); KeySpec spec = new PBEKeySpec(password, saltGenerator.generateSalt(AES_KEY_PASSWORD_SALT_LENGTH), iterations, AES_KEY_SIZE); return new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); } /** *

Constructor for SimpleGCMByteEncryptor.

* * @param config a {@link com.ulisesbocchio.jasyptspringboot.encryptor.SimpleGCMConfig} object */ public SimpleGCMByteEncryptor(SimpleGCMConfig config) { this.key = Singleton.from(this::loadSecretKey, config); this.ivGenerator = Singleton.from(config::getActualIvGenerator); this.algorithm = config.getAlgorithm(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy