home / connvers / src / main / java / avividi / connvers / crypto / Encrypter.java

Encrypter.java



package avividi.connvers.crypto;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

public class Encrypter {

  private final SecureRandom randomSecureRandom;
  private final KeyGenerator keyGenerator;
  private final Cipher cipher;

  private SecretKey key;

  Encrypter() {
    try {
      randomSecureRandom = new SecureRandom();
      keyGenerator = KeyGenerator.getInstance("AES");
      cipher = Cipher.getInstance("AES/CTR/NoPadding");
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
      throw new RuntimeException(e);
    }
  }

  void setKey(String keyB64) {
    key = new SecretKeySpec(Base64.getDecoder().decode(keyB64), "AES");
  }

  void generateKey() {
    key = keyGenerator.generateKey();

    String encodedKey = new String(Base64.getEncoder().encode(key.getEncoded()));
    System.out.printf("generated encryption key = %s\n", encodedKey);
  }

  String encrypt(String input) {
    byte[] ivBytes = new byte[cipher.getBlockSize()];
    randomSecureRandom.nextBytes(ivBytes);

    try {
      cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
      byte[] encrypted = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
      return
          new String(Base64.getEncoder().encode(ivBytes), StandardCharsets.UTF_8)
          + "-" +
          new String(Base64.getEncoder().encode(encrypted), StandardCharsets.UTF_8);
    } catch (IllegalBlockSizeException
            | InvalidAlgorithmParameterException
            | InvalidKeyException
            | BadPaddingException e) {
      throw new RuntimeException(e);
    }
  }

  String decrypt(String input) {
    String[] split = input.split("-");
    byte[] ivBytes = Base64.getDecoder().decode(split[0]);
    byte[] bodyBytes = Base64.getDecoder().decode(split[1]);

    try {
      cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivBytes));
      byte[] decrypted = cipher.doFinal(bodyBytes);
      return new String(decrypted, StandardCharsets.UTF_8);
    } catch (IllegalBlockSizeException
        | InvalidAlgorithmParameterException
        | InvalidKeyException
        | BadPaddingException e) {
      throw new RuntimeException(e);
    }
  }

}