WechatAESUtil类
public class WechatAESUtil {
/**
* 密钥算法
*/
private static final String ALGORITHM = "AES";
/**
* 加解密算法/工作模式/填充方式
*/
private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";
/**
* 生成key
*/
private static final String key = PropertyUtil.getProperty("paykey");//此处为测试key,正式环境请替换成商户密钥
private static final SecretKeySpec secretKey = new SecretKeySpec(Md5Util.MD5Encode(key, "UTF-8").toLowerCase().getBytes(), ALGORITHM);
@SuppressWarnings("unchecked")
public static void fixKeyLength()throws Exception {
String errorString = "Failed manually overriding key-length permissions.";
int newMaxKeyLength;
try {
if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
Class<?> c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
Constructor<?> con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissionCollection = con.newInstance();
Field f = c.getDeclaredField("all_allowed");
f.setAccessible(true);
f.setBoolean(allPermissionCollection, true);
c = Class.forName("javax.crypto.CryptoPermissions");
con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissions = con.newInstance();
f = c.getDeclaredField("perms");
f.setAccessible(true);
((Map<String, Object>) f.get(allPermissions)).put("*", allPermissionCollection);
c = Class.forName("javax.crypto.JceSecurityManager");
f = c.getDeclaredField("defaultPolicy");
f.setAccessible(true);
Field mf = Field.class.getDeclaredField("modifiers");
mf.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(null, allPermissions);
newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
}
} catch (Exception e) {
throw new RuntimeException(errorString, e);
}
if (newMaxKeyLength < 256)
throw new RuntimeException(errorString); // hack failed
}
/**
* AES加密
*
* @param data
* @return
* @throws Exception
*/
public static String encryptData(String data) throws Exception {
try {
// 创建密码器
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
// 初始化
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64Util.encode(cipher.doFinal(data.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* AES解密
*
* @param base64Data
* @return
* @throws Exception
*/
public static String decryptData(String base64Data) throws Exception {
try {
fixKeyLength();
//添加一个安全管理器提供者
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
//根据一个字节数组构造一个 SecretKey
/*SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); */
// 创建密码器
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
// 初始化
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64Util.decode(base64Data)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws Exception {
System.out.println("paykey"+PropertyUtil.getProperty("paykey"));
//String A 为测试字符串,是微信返回过来的退款通知字符串
String A = "eZC3Ds8xSQFRX91XA0kDrRAPcWtWUIXzv6X1Gdn+cfPF50HZHSwLuVawuYaIDUK/QJk9Ly5QiZBEiQjLl6uP+g5yP2mR8cWHWuqiJ6mheC6JHnHLS13nt0fIv58UrYMcjK4H7kx5t297gNv9hgIezk52Vbr/vMci2Xh2nOJTmroii+RnSdiWjzp3xf64MF6jeNA168KsRTlcGIBrgMThYT3EUNLaOIl90WqAmsOE01BNGn7x9ob/c9oIR3H9UJ6hYpXqpPovmNRcCxxcI5ZOt5f/2xIUYEdKAYZFp5dzN8Flywi5b3WkwmnKOzsQvlKf64MZSmk3/P0ULxKyzg3eJSSs6/X6ruVKXXIjghxp7SZglD/RMhAuCpwJLzy5UaDxkcIjfRNntfA7sXDxitxfIhMsH0QkIDoqmog8/DDQMIgvCQA9c84AeJLIoS13LM29mtLuVssybV1eGrwDRS9A3uMHHsIvP/KFeJuUcVMpMBjTh+Aql38+7J9SbMObEjVcuPnqM1YTKuRFcFQBYOX9E/9Ss7GfDYUwXL7qTLeC+pof9GEyvkTPGDaq0R+Z3wlBN4HpFo9DoNymknaeBlEw4hYFALBaEDq+a0lcWIgaORlmLzCxXCc7y5GqUU8Lyo1wZK/oIcmXZ4BH7fL4tHF5f0rKyS5KrbEqwBbi071DJL8YzChMjaYvWsq3a5AA9CIODwpXFucbpEChoIzuSCiqjyvOaL69Bt5Z3HIteFZekEaTvFfTUxKl2MAxmXRxVh86Jw2CtziveIA/BBT7JtjFpFe2DPxwylU8yRzyrotmmusVO28xuQrQtVaxG9wzD7ICtOmuNu51H0ModLvuddPjvf7+LIw9n7sSEkVL3AfPCBrsp79Kohx4ZXkQzTX/RaZSHMUfFJ9yxbEWa+UFEDYo7gw2EReXC/B1n5E2aGQDFTZsxq7+57+OR7OvPs1ant1IYqwg1IpNQgLDn7CXIXcnmUjlD8JMjSVLiiXWvdff7wzuGySOmWe7UY4sfmhm8Trn/pWt9JOzRAGThd5H+cJvxkhmQ3TH+upplIvZ41HneQM=";
String B = WechatAESUtil.decryptData(A);
System.out.println("rwerwqe"+B);
}
}
AES依赖加密包
<dependency>
<groupId>org.bouncycastle.bcprov-jdk15on.1.57.org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
<dependency>
<groupId>org.bouncycastle.bcpkix-jdk15on.1.57.org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.57</version>
</dependency>
</dependencies>
PropertyUtil.java类
package cn.web.front.common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.Properties;
/**
* @ClassName: PropertyUtil
* @Description: TODO(配置文件获取工具类)
*
*/
public class PropertyUtil {
private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);
private static Properties props;
static{
loadProps();
}
synchronized static private void loadProps(){
logger.info("开始加载properties文件内容.......");
props = new Properties();
InputStream in = null;
try {
in = PropertyUtil.class.getClassLoader().getResourceAsStream("config.properties");;
props.load(in);
} catch (FileNotFoundException e) {
logger.error("config.properties文件未找到");
} catch (IOException e) {
logger.error("出现IOException");
} finally {
try {
if(null != in) {
in.close();
}
} catch (IOException e) {
logger.error("config.properties文件流关闭出现异常");
}
}
logger.info("加载properties文件内容完成...........");
logger.info("properties文件内容:" + props);
}
public static String getProperty(String key){
if(null == props) {
loadProps();
}
return props.getProperty(key);
}
public static String getProperty(String key, String defaultValue) {
if(null == props) {
loadProps();
}
return props.getProperty(key, defaultValue);
}
public static void main(String[] args) {
System.out.println(PropertyUtil.getProperty("cos.appId"));
System.out.println(PropertyUtil.getProperty("cos.secretId"));
System.out.println(PropertyUtil.getProperty("cos.secretKey"));
System.out.println(PropertyUtil.getProperty("cos.bucketName"));
// System.out.println(PropertyUtil.getProperty("qq.clientId"));
// System.out.println(PropertyUtil.getProperty("qq.clientSecret"));
}
}