在某些场合下会碰到这个情况,如微信退款结果中加密信息的解析。
出现这个问题的原因是:java自带的是PKCS5Padding填充,不支持PKCS7Padding填充。
解决办法是:通过BouncyCastle组件来让java里面支持PKCS7Padding填充。在加解密之前加上:Security.addProvider(new BouncyCastleProvider())
,并给Cipher.getInstance方法传入参数"BC"来指定Java使用这个库里的加/解密算法。
举个解密的栗子:
/**
* @param byte[] bytes 要被解密的字节数组
* @param byte[] key 加/解密要用的长度为32的字节数组(256位)密钥
* @return String 解密后的字符串
*/
public static String Aes256Decode(byte[] bytes, byte[] key){
initialize();
String result = null;
try{
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC"); //算法即AES/ECB/PKCS7Padding
SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decoded = cipher.doFinal(bytes);
result = new String(decoded, "UTF-8");
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static void initialize(){
if (initialized) return;
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
在这段代码可以运行之前,还有一个问题需要解决。
Java本身限制密钥的长度最多128位,而AES256需要的密钥长度是256位,因此需要到Java官网上下载一个Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。
官方网站提供了JCE无限制权限策略文件的下载:
JDK6的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
JDK7的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK8的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security下覆盖原来文件,记得先备份。
如果安装了JDK,将两个jar文件也放到%JDK_HOME%\jre\lib\security下。
只要做了以上两步,就能正常加解密了。
如果还不行,可以参考这篇文章,里面提供了完整详细的例子和测试用例:https://www.cnblogs.com/jhuangsjtu/p/8261683.html。
这里提醒一个注意点:base64解码之后的结果,如果是字符串且是乱码,肯定是解码有问题,可以直接用数组。
参考资料
- https://www.cnblogs.com/jhuangsjtu/p/8261683.html
- http://blog.csdn.net/firas/article/details/47043335
- http://czj4451.iteye.com/blog/1986483
- https://www.cnblogs.com/jxldjsn/p/6097380.html