package com.bagri.support.security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* Two-way encryptor, uses Cipher API.
*
* @author Denis Sukhoroslov
*
*/
public class CipherEncryptor {
private String nonce;
private String algo;
private Cipher ecipher = null;
private Cipher dcipher = null;
/**
*
* @param algo the algorithm to use
* @param nonce the secret word
*/
public CipherEncryptor(String algo, String nonce) {
this.algo = algo;
this.nonce = nonce;
init();
}
private void init() {
if (ecipher == null || dcipher == null) {
SecretKey key;
try {
key = new SecretKeySpec(nonce.getBytes(), algo);
ecipher = Cipher.getInstance(algo);
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher = Cipher.getInstance(algo);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException e) {
throw new RuntimeException("Encryption disabled. Check if you have installed unlimited JCE policy", e);
}
}
}
/**
* Encrypts the value provided
*
* @param toEncrypt the String to encrypt
* @return the encrypted String
*/
public String encrypt(String toEncrypt) {
byte[] encrypted;
try {
String tail = String.valueOf(System.currentTimeMillis());
tail = tail.substring(tail.length() - 8);
encrypted = ecipher.doFinal((toEncrypt + tail).getBytes());
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new RuntimeException("Exception while encryption", e);
}
return new String(encrypted);
}
/**
* Decrypts the value provided
*
* @param toDecrypt the String to decrypt
* @return the decrypted String
*/
public String decrypt(String toDecrypt) {
byte[] decryptedBytes;
try {
decryptedBytes = dcipher.doFinal(toDecrypt.getBytes());
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new RuntimeException("Exception while decryption", e);
}
String decrypted = new String(decryptedBytes);
return decrypted.substring(0, decrypted.length() - 8);
}
private static String algo_name = "AES";
/**
* Encrypts the value provided using AES algorithm
*
* @param toEncrypt the String to encrypt
* @param nonce the secret word
* @return the encrypted String
*/
public static String encrypt(String toEncrypt, String nonce) {
SecretKey key;
try {
key = new SecretKeySpec(nonce.getBytes(), algo_name);
Cipher ecipher = Cipher.getInstance(algo_name);
ecipher.init(Cipher.ENCRYPT_MODE, key);
String tail = String.valueOf(System.currentTimeMillis());
tail = tail.substring(tail.length() - 8);
byte[] encrypted = ecipher.doFinal((toEncrypt + tail).getBytes());
return new String(encrypted);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Decrypts the value provided using AES algorithm
*
* @param toDecrypt the String to decrypt
* @param nonce the secret word
* @return the decrypted String
*/
public static String decrypt(String toDecrypt, String nonce) {
SecretKey key;
try {
key = new SecretKeySpec(nonce.getBytes(), algo_name);
Cipher dcipher = Cipher.getInstance(algo_name);
dcipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = dcipher.doFinal(toDecrypt.getBytes());
return new String(decrypted, 0, decrypted.length - 8);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}