com.groupbyinc.common.security.AesEncryption Maven / Gradle / Ivy
package com.groupbyinc.common.security;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import static com.groupbyinc.common.security.AesUtil.geEncryptSalt;
import static com.groupbyinc.common.security.AesUtil.getMessageAuthenticationCodeSalt;
public class AesEncryption {
public static final int CLIENT_KEY_HASHING_ITERATIONS = 5000;
private SecretKey encryptionKey;
private SecretKey macKey;
private Cipher cipher;
private Mac hmac;
public AesEncryption(String clientKey, String customerId) throws InvalidKeySpecException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
this(clientKey, customerId, new BouncyCastleProvider());
}
public AesEncryption(String clientKey, String customerId, Provider provider) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
Security.addProvider(provider);
cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(clientKey.toCharArray(), geEncryptSalt(customerId).getBytes(StandardCharsets.UTF_8), CLIENT_KEY_HASHING_ITERATIONS, 128);
KeySpec macSpec = new PBEKeySpec(clientKey.toCharArray(), getMessageAuthenticationCodeSalt(customerId).getBytes(StandardCharsets.UTF_8), CLIENT_KEY_HASHING_ITERATIONS, 160);
encryptionKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
macKey = new SecretKeySpec(factory.generateSecret(macSpec).getEncoded(), "HmacSHA256");
hmac = Mac.getInstance("HmacSHA256");
hmac.init(macKey);
}
public AesContent encrypt(String message) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
if (StringUtils.isBlank(message)) {
throw new IllegalStateException("cannot encrypt null message");
}
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new SecureRandom());
byte[] cipherText = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
byte[] encodedCipherText = Base64.encodeBase64(cipherText);
byte[] iv = cipher.getIV();
byte[] encodedIv = Base64.encodeBase64(iv);
byte[] ciperTextAndIv = new byte[cipherText.length + iv.length];
System.arraycopy(cipherText, 0, ciperTextAndIv, 0, cipherText.length);
System.arraycopy(iv, 0, ciperTextAndIv, cipherText.length, iv.length);
byte[] mac = hmac.doFinal(ciperTextAndIv);
byte[] encodedMac = Base64.encodeBase64(mac);
return new AesContent(new String(encodedCipherText, StandardCharsets.UTF_8), new String(encodedIv, StandardCharsets.UTF_8), new String(encodedMac, StandardCharsets.UTF_8));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy