CryptoUtils.java
/*
* @copyright defined in LICENSE.txt
*/
package hera.util;
import static java.lang.System.arraycopy;
import com.google.common.io.BaseEncoding;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
public class CryptoUtils {
public static final String CIPHER_CHARSET = "UTF-8";
public static final String CIPHER_NAME = "AES/ECB/PKCS5Padding";
protected static final String DEFAULT_PASSWORD = "tn595hil2n9kolh9";
protected static SecureRandom random;
protected static MessageDigest sha;
protected static MessageDigest md5;
protected static SecretKeySpec keySpec;
static {
try {
random = SecureRandom.getInstance("SHA1PRNG");
sha = MessageDigest.getInstance("SHA-1");
md5 = MessageDigest.getInstance("MD5");
keySpec = new SecretKeySpec(DEFAULT_PASSWORD.getBytes("UTF-8"), "AES");
} catch (final Throwable th) {
throw new IllegalStateException(th);
}
}
/**
* Create secret from password.
*
* @param password string to create secret from
* @param length secret length
*
* @return secret to be created
*/
public static SecretKeySpec createSecret(final byte[] password, final int length) {
final byte[] fixedLengthPassword = new byte[length];
Arrays.fill(fixedLengthPassword, (byte) 0);
arraycopy(password, 0, fixedLengthPassword, 0,
Math.min(fixedLengthPassword.length, password.length));
return new SecretKeySpec(fixedLengthPassword, "AES");
}
/**
* Encoding with Base64 and Aes128Ecb.
*
* @param source string to encode
*
* @return encoded string
*
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static String encryptToAes128EcbWithBase64(final String source)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
return encryptToAes128EcbWithBase64(source, DEFAULT_PASSWORD);
}
/**
* Encoding with Base64 and Aes128Ecb.
*
* @param source string to encode
* @param password password to encode with
*
* @return encoded string
*
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static String encryptToAes128EcbWithBase64(final String source, final String password)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(password.getBytes("UTF-8"), "AES");
return encryptToAes128EcbWithBase64(source.getBytes(CIPHER_CHARSET), secretKeySpec);
} catch (final UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
/**
* Encoding with Base64 and Aes128Ecb.
*
* @param message byte array to encode
* @param secretKeySpec secret key information
* @return encoded string
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static String encryptToAes128EcbWithBase64(final byte[] message,
final SecretKeySpec secretKeySpec) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// Encrypt in 16 bytes (128bit) Block
final javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_NAME);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKeySpec);
final byte[] aes128ecb = cipher.doFinal(message);
return BaseEncoding.base64().encode(aes128ecb);
}
/**
* Encrypt to aes with gcm.
*
* @param message message to encrypt
* @param password encrypt key
* @param nonce an encrypt nonce
* @return encrypted bytes
*
* @throws IllegalStateException if the cipher is in an inappropriate state
* @throws InvalidCipherTextException if the MAC fails to match
*/
public static byte[] encryptToAesGcm(final byte[] message, final byte[] password,
final byte[] nonce) throws IllegalStateException, InvalidCipherTextException {
final GCMBlockCipher cppher = new GCMBlockCipher(new AESEngine());
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(password), nonce);
cppher.init(true, ivAndKey);
final byte[] outBuf = new byte[cppher.getOutputSize(message.length)];
int outOff = cppher.processBytes(message, 0, message.length, outBuf, 0);
cppher.doFinal(outBuf, outOff);
return outBuf;
}
/**
* Decode with Base64 and Aes128Ecb.
*
* @param source string to decode
* @return decoded string
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static byte[] decryptFromAes128EcbWithBase64(final String source)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
return decryptFromAes128EcbWithBase64(source, DEFAULT_PASSWORD);
}
/**
* Decode with Base64 and Aes128Ecb.
*
* @param source string to decode
* @param password spring to decode with
*
* @return decoded string
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static byte[] decryptFromAes128EcbWithBase64(final String source, final String password)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(password.getBytes("UTF-8"), "AES");
return decryptFromAes128EcbWithBase64(source, secretKeySpec);
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
/**
* Decode with Base64 and Aes128Ecb.
*
* @param source string to decode
* @param secretKeySpec secret to decode with
*
* @return decoded string
* @throws NoSuchAlgorithmException if no algorithm
* @throws NoSuchPaddingException if no padding exist
* @throws InvalidKeyException if invalid key used
* @throws IllegalBlockSizeException if wrong block size
* @throws BadPaddingException if padding violate rule
*/
public static byte[] decryptFromAes128EcbWithBase64(final String source,
final SecretKeySpec secretKeySpec) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
final byte[] decodedBase64 = BaseEncoding.base64().decode(source);
final javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_NAME);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKeySpec);
final byte[] decoded = cipher.doFinal(decodedBase64);
return decoded;
}
/**
* Decrypt to aes with gcm.
*
* @param source source to decrypt
* @param password encrypt key
* @param nonce an encrypt nonce
* @return decryp bytes
*
* @throws IllegalStateException if the cipher is in an inappropriate state
* @throws InvalidCipherTextException if the MAC fails to match
*/
public static byte[] decryptFromAesGcm(final byte[] source, final byte[] password,
final byte[] nonce) throws IllegalStateException, InvalidCipherTextException {
final GCMBlockCipher cppher = new GCMBlockCipher(new AESEngine());
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(password), nonce);
cppher.init(false, ivAndKey);
final byte[] outBuf = new byte[cppher.getOutputSize(source.length)];
int outOff = cppher.processBytes(source, 0, source.length, outBuf, 0);
cppher.doFinal(outBuf, outOff);
return outBuf;
}
}