直接上代码
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Encrypt {
public static boolean initialized = false;
public static final String ALGORITHM = "AES/ECB/PKCS7Padding";
/**
* @param String str 要被加密的字符串
* @param byte[] key 加/解密要用的长度为32的字节数组(256位)密钥
* @return byte[] 加密后的字节数组
*/
public static byte[] Aes256Encode(String str, byte[] key){
initialize();
byte[] result = null;
try{
Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); //生成加密解密需要的Key
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
result = cipher.doFinal(str.getBytes("UTF-8"));
}catch(Exception e){
e.printStackTrace();
}
return result;
}
/**
* @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");
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;
}
}
测试调用的代码
public static void main(String[] args) throws Exception {
String md5Key = MD5Util.MD5Encode("你的apikey", "UTF-8").toLowerCase();
byte[] key = md5Key.getBytes();
String a = "微信回调返回来的加密串,根据req_info取出的";
byte[] b = Base64Util.decode(a);
System.out.println(Encrypt.Aes256Decode(b, key));
}
问题1:
- 代码开头要先import Java Cryptography Extension (JCE)中的两个类——加/解密类Cipher和密钥类SecretKeySpec,以及BouncyCastle的一个开源加/解密类库中的加/解密算法提供者类BouncyCastleProvider。
PC上的Java里面只有"AES/ECB/PKCS5Padding"算法,没有"AES/ECB/PKCS7Padding"算法。故需要引入BouncyCastle的库,并给Cipher.getInstance方法传入参数"BC"来指定Java使用这个库里的加/解密算法。BouncyCastle的加/解密类库的下载地址:http://www.bouncycastle.org/latest_releases.html
也可以是使用maven
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.45</version>
</dependency>
问题2:
用AES解密时出现"java.security.InvalidKeyException: Illegal key size"异常。
如果密钥大于128, 会抛出上述异常。因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件,文件位于/jre/lib/security下, 这种限制是因为美国对软件出口的控制。解决办法也很简单:
jdk对应jar包的路径:D:\Java\jdk1.7.0_25\jre\lib\security
jre对应jar包的路径:D:\Java\jre7\lib\security
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目录下覆盖原来文件