org.jivesoftware.util.AesEncryptor Maven / Gradle / Ivy
The newest version!
package org.jivesoftware.util;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility class providing symmetric AES encryption/decryption. To strengthen
* the encrypted result, use the {@link #setKey} method to provide a custom
* key prior to invoking the {@link #encrypt} or {@link #decrypt} methods.
*
* @author Tom Evans
*/
public class AesEncryptor implements Encryptor {
private static final Logger log = LoggerFactory.getLogger(AesEncryptor.class);
private static final String ALGORITHM = "AES/CBC/PKCS7Padding";
private static final byte[] INIT_PARM =
{
(byte)0xcd, (byte)0x91, (byte)0xa7, (byte)0xc5,
(byte)0x27, (byte)0x8b, (byte)0x39, (byte)0xe0,
(byte)0xfa, (byte)0x72, (byte)0xd0, (byte)0x29,
(byte)0x83, (byte)0x65, (byte)0x9d, (byte)0x74
};
private static final byte[] DEFAULT_KEY =
{
(byte)0xf2, (byte)0x46, (byte)0x5d, (byte)0x2a,
(byte)0xd1, (byte)0x73, (byte)0x0b, (byte)0x18,
(byte)0xcb, (byte)0x86, (byte)0x95, (byte)0xa3,
(byte)0xb1, (byte)0xe5, (byte)0x89, (byte)0x27
};
private static boolean isInitialized = false;
private byte[] cipherKey = null;
/** Default constructor */
public AesEncryptor() { initialize(); }
/** Custom key constructor */
public AesEncryptor(String key) {
initialize();
setKey(key);
}
/* (non-Javadoc)
* @see org.jivesoftware.util.Encryptor#encrypt(java.lang.String)
*/
@Override
public String encrypt(String value)
{
if (value == null) { return null; }
byte [] bytes = value.getBytes(StandardCharsets.UTF_8);
return Base64.encodeBytes( cipher(bytes, getKey(), Cipher.ENCRYPT_MODE) );
}
/* (non-Javadoc)
* @see org.jivesoftware.util.Encryptor#decrypt(java.lang.String)
*/
@Override
public String decrypt(String value)
{
if (value == null) { return null; }
byte [] bytes = cipher(Base64.decode(value), getKey(), Cipher.DECRYPT_MODE);
if (bytes == null) { return null; }
return new String(bytes, StandardCharsets.UTF_8);
}
/**
* Symmetric encrypt/decrypt routine.
*
* @param attribute The value to be converted
* @param key The encryption key
* @param mode The cipher mode (encrypt or decrypt)
* @return The converted attribute, or null if conversion fails
*/
private byte [] cipher(byte [] attribute, byte [] key, int mode)
{
byte [] result = null;
try
{
// Create AES encryption key
Key aesKey = new SecretKeySpec(key, "AES");
// Create AES Cipher
Cipher aesCipher = Cipher.getInstance(ALGORITHM);
// Initialize AES Cipher and convert
aesCipher.init(mode, aesKey, new IvParameterSpec(INIT_PARM));
result = aesCipher.doFinal(attribute);
}
catch (Exception e)
{
log.error("AES cipher failed", e);
}
return result;
}
/**
* Return the encryption key. This will return the user-defined
* key (if available) or a default encryption key.
*
* @return The encryption key
*/
private byte [] getKey()
{
return cipherKey == null ? DEFAULT_KEY : cipherKey;
}
/**
* Set the encryption key. This will apply the user-defined key,
* truncated or filled (via the default key) as needed to meet
* the key length specifications.
*
* @param key The encryption key
*/
private void setKey(byte [] key)
{
cipherKey = editKey(key);
}
/* (non-Javadoc)
* @see org.jivesoftware.util.Encryptor#setKey(java.lang.String)
*/
@Override
public void setKey(String key)
{
if (key == null) {
cipherKey = null;
return;
}
byte [] bytes = key.getBytes(StandardCharsets.UTF_8);
setKey(editKey(bytes));
}
/**
* Validates an optional user-defined encryption key. Only the
* first sixteen bytes of the input array will be used for the key.
* It will be filled (if necessary) to a minimum length of sixteen.
*
* @param key The user-defined encryption key
* @return A valid encryption key, or null
*/
private byte [] editKey(byte [] key)
{
if (key == null) { return null; }
byte [] result = new byte [DEFAULT_KEY.length];
for (int x=0; x