import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Component;
/**
* AES encryption and decryption tool.
* @see http://lixuanbin.iteye.com/blog/2078020
* @author sky
*
*/
@Component
public class AESTool {
private static final String CHARSET = "UTF-8";
private String key;
private byte[] initVector = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 };
/**
* Encrypt the content with a given key using aes algorithm.
* 使用aes算法对内容进行加密
* @param content
* @param key
* must contain exactly 32 characters
* @return
* @throws Exception
*/
public String encrypt(String content) throws Exception {
if (key == null) {
throw new IllegalArgumentException("Key cannot be null!");
}
String encrypted = null;
byte[] keyBytes = key.getBytes(CHARSET);
if (keyBytes.length != 32 && keyBytes.length != 24
&& keyBytes.length != 16) {
throw new IllegalArgumentException(
"Key length must be 128/192/256 bits!");
}
byte[] encryptedBytes = null;
encryptedBytes = encrypt(Base64.encode(content.getBytes(CHARSET)), keyBytes, initVector);
encrypted = new String(Hex.encode(encryptedBytes));
return encrypted;
}
/**
* Decrypt the content with a given key using aes algorithm.
* 使用aes算法对内容进行解密
* @param content
* @param key
* must contain exactly 32 characters
* @return
* @throws Exception
*/
public String decrypt(String content) throws Exception {
if (key == null) {
throw new IllegalArgumentException("Key cannot be null!");
}
String decrypted = null;
byte[] encryptedContent = Hex.decode(content);
byte[] keyBytes = key.getBytes(CHARSET);
byte[] decryptedBytes = null;
if (keyBytes.length != 32 && keyBytes.length != 24
&& keyBytes.length != 16) {
throw new IllegalArgumentException(
"Key length must be 128/192/256 bits!");
}
decryptedBytes = decrypt(encryptedContent, keyBytes, initVector);
decrypted = new String(Base64.decode(decryptedBytes));
return decrypted;
}
/**
* Encrypt data.
*
* @param plain
* @param key
* @param iv
* @return
* @throws Exception
*/
public byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESFastEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}
/**
* Decrypt data.
* 解密数据
* @param cipher
* @param key
* @param iv
* @return
* @throws Exception
*/
public byte[] decrypt(byte[] cipher, byte[] key, byte[] iv)
throws Exception {
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(
new CBCBlockCipher(new AESFastEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key),
iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
/**
* Encrypt or decrypt data.
* 加密或解密数据
* @param cipher
* @param data
* @return
* @throws Exception
*/
private byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
throws Exception {
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
public static void main(String[] args) throws Exception {
byte[] initVector = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 };
// LOG.debug(new String(initVector));
System.out.println(new String(initVector));
AESTool aesTool = new AESTool();
aesTool.setKey("7BFD6AB2227C4822");
String xml = "{\"SERVICE\":{\"SERVICE_HEADER\":{\"SERVICE_ID\":\"TNQPLPAllLoanFeeDef\",\"ORG\":\"000000000001\",\"CHANNEL_ID\":\"BANK\",\"ACQ_ID\":\"00000000\",\"SUB_TERMINAL_TYPE\":\"RMPS\",\"SERVICESN\":\"APP2016032409295126650\",\"OP_ID\":null,\"REQUEST_TIME\":\"20160324092951\",\"VERSION_ID\":\"01\",\"MAC\":null,\"SERV_RESPONSE\":null},\"SERVICE_BODY\":{\"REQUEST\":{\"LOAN_CODE\":null},\"RESPONSE\":null}}}{\"SERVICE\":{\"SERVICE_HEADER\":{\"SERVICE_ID\":\"TNQPLPAllLoanFeeDef\",\"ORG\":\"000000000001\",\"CHANNEL_ID\":\"BANK\",\"ACQ_ID\":\"00000000\",\"SUB_TERMINAL_TYPE\":\"RMPS\",\"SERVICESN\":\"APP2016032409295126650\",\"OP_ID\":null,\"REQUEST_TIME\":\"20160324092951\",\"VERSION_ID\":\"01\",\"MAC\":null,\"SERV_RESPONSE\":null},\"SERVICE_BODY\":{\"REQUEST\":{\"LOAN_CODE\":null},\"RESPONSE\":null}}}";
String encrypted = aesTool.encrypt(xml);
String decrypted = aesTool.decrypt(encrypted);
System.out.println("encrypte加密"+encrypted);
System.out.println("decrypted解密"+decrypted);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}