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

com.groupbyinc.common.security.AesEncryption Maven / Gradle / Ivy

There is a newer version: 198
Show newest version
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