微信退款回调解密req_info时报错:Illegal key size or default parameters.
- 微信官方文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10#menu1
解密方式
解密步骤如下:
(1)对加密串A做base64解码,得到加密串B
(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台 (pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置 )
(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
解密时报错的解决方案就是【重点在这里】:
- 首先在oracle官方下载jce_policy,我的是jdk8
- 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
下载后我们把jce_policy这个zip解压,我们可以看到两个jar包
把刚刚下载的两个jar包到jdk、jre中替换到这个里面
Java\jdk1.8.0_71\jre\lib\security\里面的两个jar替换掉
Java\jre1.8.0_71\lib\security\里面的两个jar替换掉
这里是我退款成功后的回调代码:
@PostMapping("/refundNotify")
public String refund(HttpServletRequest request) {
System.out.println("退款回调的请求方式" + request.getMethod());
String xmlSuccess = "<xml>\n" +
" <return_code><![CDATA[SUCCESS]]></return_code>\n" +
" <return_msg><![CDATA[OK]]></return_msg>\n" +
"</xml>";
String xmlFail = "<xml>\n" +
" <return_code><![CDATA[FAIL]]></return_code>\n" +
" <return_msg><![CDATA[OK]]></return_msg>\n" +
"</xml>";
try {
String xmlResult = PayUtil.getPostStr(request);
Map<String, String> resultMap = null;
try {
//将结果转成map
resultMap = PayUtil.xmlToMap(xmlResult);
} catch (Exception e1) {
e1.printStackTrace();
}
//商户订单号
String req_info = resultMap.get("req_info");
String return_code = resultMap.get("return_code");
if ("SUCCESS".equals(return_code)) {
//解密步骤如下:
//(1)对加密串A做base64解码,得到加密串B
Base64.Decoder decoder = Base64.getDecoder();
byte[] base64ByteArr = decoder.decode(req_info);
//(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
String key = MD5(PayConfig.KEY).toLowerCase();
//(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)*/
String xml = init(key,base64ByteArr);
Map<String,String> xmlMasp = PayUtil.xmlToMap(xml);
String orderId = xmlMasp.get("out_trade_no");
System.err.println("退款单号:" + orderId);
Result res = orderService.refundSuccessUpdateStatus(orderId);//根据商户订单号ID更新状态
if (res.getCode() == 200) {
System.out.println("退款成功,并且订单状态已更新");
return xmlSuccess;
}
}
} catch (Exception e) {
System.out.println("退款失败,发生异常,可能由于:" + e.getMessage());
return xmlFail;
}
return xmlFail;
}
/**
* 生成 MD5
* 微信SDK中的生成MD5方法
*
* @param data 待处理数据
* @return MD5结果
*/
private static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
private static String init(String key,byte[] str){
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(),"AES");
Security.addProvider(new BouncyCastleProvider());
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
String result = new String(cipher.doFinal(str));
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}