package com.app.pay.common.util;
import java.security.AlgorithmParameters;
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 com.ods.common.util.Base64Util;
/**
* @FileName AESUtil.java
* @Description:
*
* @Date 2019年2月13日
* @author pangxianhe
*
*/
public class AESUtil {
//加密方式
public static String KEY_ALGORITHM = "AES";
//数据填充方式
public static String algorithmStr = "AES/CBC/PKCS5Padding";
//避免重复new生成多个BouncyCastleProvider对象,因为GC回收不了,会造成内存溢出
//只在第一次调用decrypt()方法时才new 对象
public static boolean initialized = false;
/**
* 加密
* @param content
* @param Key
* @param ivStr
* @return
* @author pangxianhe
* @date 2019年2月13日
*/
public static String encrypt(String content, String Key, String ivStr) {
initialize();
try {
Cipher cipher = Cipher.getInstance(algorithmStr);
SecretKeySpec skeySpec = new SecretKeySpec(Key.getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(ivStr.getBytes()));
byte[] encrypted = cipher.doFinal(content.getBytes());
return Base64Util.encode(encrypted);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 解密
* @param content
* @param aesKey
* @param iv
* @return
* @author pangxianhe
* @date 2019年2月13日
*/
public static String decrypt(String content, String aesKey, String iv) {
initialize();
try {
byte[] encrypted1 = Base64Util.decode(content);//先用base64解密
Cipher cipher = Cipher.getInstance(algorithmStr);
Key sKeySpec = new SecretKeySpec(aesKey.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(iv.getBytes()));// 初始化
byte[] result = cipher.doFinal(encrypted1);
String originalString = new String(result);
return originalString;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**BouncyCastle作为安全提供,防止我们加密解密时候因为jdk内置的不支持改模式运行报错。**/
public static void initialize() {
if (initialized)
return;
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
// 生成iv
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(iv));
return params;
}
public static void main(String[] args) throws Exception {
/*
* 加密用的Key 可以用26个字母和数字组成,最好不要用保留字符,虽然不会错,至于怎么裁决,个人看情况而定
* 此处使用AES-128-CBC加密模式,key需要为16位。
*/
// 需要加密的字串
String cSrc = "{data:[{'name':'你好','age':20},{'name':'zd','age':18}]}";
String cKey = "qwqw1234qwqw1234qwqw1234szqwqw12";
String vi = "0000000000000000";
System.out.println(cSrc);
// 加密
long lStart = System.currentTimeMillis();
String enString = AESUtil.encrypt(cSrc, cKey,vi);
System.out.println("加密后的字串是:" + enString);
long lUseTime = System.currentTimeMillis() - lStart;
System.out.println("加密耗时:" + lUseTime + "毫秒");
// 解密
lStart = System.currentTimeMillis();
String DeString = AESUtil.decrypt(enString, cKey,vi);
System.out.println("解密后的字串是:" + DeString);
lUseTime = System.currentTimeMillis() - lStart;
System.out.println("解密耗时:" + lUseTime + "毫秒");
}
}
此处加密的key是qwqw1234qwqw1234
,如果修改为32位或者更高位的的将会报java.security.InvalidKeyException: Illegal key size
解决办法:
下载对应的jar文件替换原有的,
jdk1.8的http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html。
其他版本的与之类似,下载好后解压,主要用到local_policy.jar和US_export_policy.jar,将其复制到JAVA_HOME下的\jre\lib\security中替换,即可