官方给出的开发文档解密步骤如下: 
(1)对加密串A做base64解码,得到加密串B
(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )

(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)

准备工作:

依赖:

      <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.47</version></dependency>

第三步的解密算法需要用到。
2.因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件,  从官方网站下载JCE无限制权限策略文件,注意自己JDK的版本别下错了。将local_policy.jar和US_export_policy.jar这两个文件替换%JDK_HOME%\jre\lib\security下原来的文件,注意先备份原文件。

官方网站提供了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。
如果安装了JDK,将两个jar文件也放到%JDK_HOME%\jre\lib\security下 覆盖原来文件,记得先备份。。

然后在%JDK_HOME%\jre\lib\security添加语句

3、修改java.security文件

security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

编写代码:

public class Base64Util {private static final char S_BASE64CHAR[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S','T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};private static final byte S_DECODETABLE[];static {S_DECODETABLE = new byte[128];for (int i = 0; i < S_DECODETABLE.length; i++)S_DECODETABLE[i] = 127;for (int i = 0; i < S_BASE64CHAR.length; i++)S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i;}/*** @param ibuf* @param obuf* @param wp* @return*/private static int decode0(char ibuf[], byte obuf[], int wp) {int outlen = 3;if (ibuf[3] == '=')outlen = 2;if (ibuf[2] == '=')outlen = 1;int b0 = S_DECODETABLE[ibuf[0]];int b1 = S_DECODETABLE[ibuf[1]];int b2 = S_DECODETABLE[ibuf[2]];int b3 = S_DECODETABLE[ibuf[3]];switch (outlen) {case 1: // '\001'obuf[wp] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);return 1;case 2: // '\002'obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);obuf[wp] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15);return 2;case 3: // '\003'obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);obuf[wp++] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15);obuf[wp] = (byte) (b2 << 6 & 192 | b3 & 63);return 3;}throw new RuntimeException("Internal error");}/*** @param data* @param off* @param len* @return*/public static byte[] decode(char data[], int off, int len) {char ibuf[] = new char[4];int ibufcount = 0;byte obuf[] = new byte[(len / 4) * 3 + 3];int obufcount = 0;for (int i = off; i < off + len; i++) {char ch = data[i];if (ch != '=' && (ch >= S_DECODETABLE.length || S_DECODETABLE[ch] == 127))continue;ibuf[ibufcount++] = ch;if (ibufcount == ibuf.length) {ibufcount = 0;obufcount += decode0(ibuf, obuf, obufcount);}}if (obufcount == obuf.length) {return obuf;} else {byte ret[] = new byte[obufcount];System.arraycopy(obuf, 0, ret, 0, obufcount);return ret;}}/*** @param data* @return*/public static byte[] decode(String data) {char ibuf[] = new char[4];int ibufcount = 0;byte obuf[] = new byte[(data.length() / 4) * 3 + 3];int obufcount = 0;for (int i = 0; i < data.length(); i++) {char ch = data.charAt(i);if (ch != '=' && (ch >= S_DECODETABLE.length || S_DECODETABLE[ch] == 127))continue;ibuf[ibufcount++] = ch;if (ibufcount == ibuf.length) {ibufcount = 0;obufcount += decode0(ibuf, obuf, obufcount);}}if (obufcount == obuf.length) {return obuf;} else {byte ret[] = new byte[obufcount];System.arraycopy(obuf, 0, ret, 0, obufcount);return ret;}}/*** @param data* @param off* @param len* @param ostream* @throws*/public static void decode(char data[], int off, int len, OutputStream ostream) throws IOException {char ibuf[] = new char[4];int ibufcount = 0;byte obuf[] = new byte[3];for (int i = off; i < off + len; i++) {char ch = data[i];if (ch != '=' && (ch >= S_DECODETABLE.length || S_DECODETABLE[ch] == 127))continue;ibuf[ibufcount++] = ch;if (ibufcount == ibuf.length) {ibufcount = 0;int obufcount = decode0(ibuf, obuf, 0);ostream.write(obuf, 0, obufcount);}}}/*** @param data* @param ostream* @throws IOException*/public static void decode(String data, OutputStream ostream) throws IOException {char ibuf[] = new char[4];int ibufcount = 0;byte obuf[] = new byte[3];for (int i = 0; i < data.length(); i++) {char ch = data.charAt(i);if (ch != '=' && (ch >= S_DECODETABLE.length || S_DECODETABLE[ch] == 127))continue;ibuf[ibufcount++] = ch;if (ibufcount == ibuf.length) {ibufcount = 0;int obufcount = decode0(ibuf, obuf, 0);ostream.write(obuf, 0, obufcount);}}}/*** @param data* @return*/public static String encode(byte data[]) {return encode(data, 0, data.length);}/*** @param data* @param off* @param len* @return*/public static String encode(byte data[], int off, int len) {if (len <= 0)return "";char out[] = new char[(len / 3) * 4 + 4];int rindex = off;int windex = 0;int rest;for (rest = len - off; rest >= 3; rest -= 3) {int i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);out[windex++] = S_BASE64CHAR[i >> 18];out[windex++] = S_BASE64CHAR[i >> 12 & 63];out[windex++] = S_BASE64CHAR[i >> 6 & 63];out[windex++] = S_BASE64CHAR[i & 63];rindex += 3;}if (rest == 1) {int i = data[rindex] & 255;out[windex++] = S_BASE64CHAR[i >> 2];out[windex++] = S_BASE64CHAR[i << 4 & 63];out[windex++] = '=';out[windex++] = '=';} else if (rest == 2) {int i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);out[windex++] = S_BASE64CHAR[i >> 10];out[windex++] = S_BASE64CHAR[i >> 4 & 63];out[windex++] = S_BASE64CHAR[i << 2 & 63];out[windex++] = '=';}return new String(out, 0, windex);}/*** @param data* @param off* @param len* @param ostream* @throws IOException*/public static void encode(byte data[], int off, int len, OutputStream ostream) throws IOException {if (len <= 0)return;byte out[] = new byte[4];int rindex = off;int rest;for (rest = len - off; rest >= 3; rest -= 3) {int i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);out[0] = (byte) S_BASE64CHAR[i >> 18];out[1] = (byte) S_BASE64CHAR[i >> 12 & 63];out[2] = (byte) S_BASE64CHAR[i >> 6 & 63];out[3] = (byte) S_BASE64CHAR[i & 63];ostream.write(out, 0, 4);rindex += 3;}if (rest == 1) {int i = data[rindex] & 255;out[0] = (byte) S_BASE64CHAR[i >> 2];out[1] = (byte) S_BASE64CHAR[i << 4 & 63];out[2] = 61;out[3] = 61;ostream.write(out, 0, 4);} else if (rest == 2) {int i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);out[0] = (byte) S_BASE64CHAR[i >> 10];out[1] = (byte) S_BASE64CHAR[i >> 4 & 63];out[2] = (byte) S_BASE64CHAR[i << 2 & 63];out[3] = 61;ostream.write(out, 0, 4);}}/*** @param data* @param off* @param len* @param writer* @throws IOException*/public static void encode(byte data[], int off, int len, Writer writer) throws IOException {if (len <= 0)return;char out[] = new char[4];int rindex = off;int rest = len - off;int output = 0;do {if (rest < 3)break;int i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);out[0] = S_BASE64CHAR[i >> 18];out[1] = S_BASE64CHAR[i >> 12 & 63];out[2] = S_BASE64CHAR[i >> 6 & 63];out[3] = S_BASE64CHAR[i & 63];writer.write(out, 0, 4);rindex += 3;rest -= 3;if ((output += 4) % 76 == 0)writer.write("\n");}while (true);if (rest == 1) {int i = data[rindex] & 255;out[0] = S_BASE64CHAR[i >> 2];out[1] = S_BASE64CHAR[i << 4 & 63];out[2] = '=';out[3] = '=';writer.write(out, 0, 4);} else if (rest == 2) {int i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);out[0] = S_BASE64CHAR[i >> 10];out[1] = S_BASE64CHAR[i >> 4 & 63];out[2] = S_BASE64CHAR[i << 2 & 63];out[3] = '=';writer.write(out, 0, 4);}}}

public class MD5Util {public final static String MD5(String s) {char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };try {byte[] btInput = s.getBytes();// 获得MD5摘要算法的 MessageDigest 对象MessageDigest mdInst = MessageDigest.getInstance("MD5");// 使用指定的字节更新摘要mdInst.update(btInput);// 获得密文byte[] md = mdInst.digest();// 把密文转换成十六进制的字符串形式int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);}catch (Exception e) {e.printStackTrace();return null;}}private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++)resultSb.append(byteToHexString(b[i]));return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0)n += 256;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (charsetname == null || "".equals(charsetname))resultString = byteArrayToHexString(md.digest(resultString.getBytes()));elseresultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));}catch (Exception exception) {}return resultString;}private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };public static void main(String[] asd) {String con = "hello kitty";String str = MD5Encode(con, "UTF-8");System.out.println(str.toUpperCase());}
}
@Testvoid contextLoads() throws Exception {// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//String A 为测试字符串,是微信返回过来的退款通知字符串String A = "1111";String B =decryptData(A);System.out.println(B);}/*** 密钥算法*/private static final String ALGORITHM = "AES";/*** 加解密算法/工作模式/填充方式*/private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";/*** 生成key*/private static final String key = "key";//此处为测试key,正式环境请替换成商户密钥private static SecretKeySpec secretKey = new SecretKeySpec(MD5Util.MD5Encode(key, "UTF-8").toLowerCase().getBytes(), ALGORITHM);/*** AES加密** @param data* @return* @throws Exception*/public static String encryptData(String data) throws Exception {// 创建密码器Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);// 初始化cipher.init(Cipher.ENCRYPT_MODE, secretKey);return Base64Util.encode(cipher.doFinal(data.getBytes()));}/*** AES解密** @param base64Data* @return* @throws Exception*/public  String decryptData(String base64Data) throws Exception {// 创建密码器Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);// 初始化cipher.init(Cipher.DECRYPT_MODE, secretKey);return new String(cipher.doFinal(Base64Util.decode(base64Data)));}

如果不懂 可以去看看这个

https://shentuzhigang.blog.csdn.net/article/details/107330649

微信支付退款通知解密(req_info)相关推荐

  1. 微信接口java解密_java使用AES-256-ECB(PKCS7Padding)解密——微信支付退款通知接口指定解密方式...

    1.场景 在做微信支付退款通知接口时,微信对通知的内容做了加密,并且指定用 AES256 解密,官方指定的解密方式如下: 2.导包 org.bouncycastle bcprov-jdk15on 1. ...

  2. 【微信公众号开发】微信支付-退款通知

    就算商户系统没有开通微信退款结果通知,微信也会自己发送消息告诉用户退款流程和结果.如果是立马到账的,会直接发送退款结果通知:非立马到账的,会先发一条"退款发起通知",到账之后再发一 ...

  3. 微信支付退款结果通知解密 base64_decode / md5 / AES

    转自 https://jishu8.net/tag/wxpay 微信支付退款结果通知解密步骤如下: 第一步,对商户密钥key进行MD5加密,得到32位小写加密串StringA key设置路径:微信商户 ...

  4. 微信小程序开发实战11_4 微信支付退款流程

    当交易发生之后一年内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付金额退还给买家,微信支付将收到退款请求并且验证成功之后,将支付款按原路退还至买家账号上.使用该接口时的一些注意事项如下 ...

  5. Java 微信小程序笔记 二、 微信支付退款案例

    一.前期准备工作: 上篇博客配置的一些参数和文件Jar包 都要用到 微信支付需要小程序和商户绑定 APP绑定微信商户平台获取商户id(mchID). 证书(商户后台下载). 支付签名密钥(商户后台设置 ...

  6. java 中实现微信支付退款功能案例

    微信支付功能做了太多,今天又做了支付.退款.查询.提现等等,顺便把支付和退款代码贴出来,希望对初学者有点帮助. 首先调用微信支付退款 API 地址 https://pay.weixin.qq.com/ ...

  7. 微信支付AES加解密算法

    微信支付AES加解密算法 AES256/ECB/PKCS7Padding 一.AES 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法 二. ...

  8. java 微信退款配置_微信支付退款配置

    微信支付退款配置 1.微信支付配置 第一步,登录商城后台,设置->交易设置->支付配置 ,选择微信支付,点击配置进入到微信支付参数配置界面. 从应用ID和应用密钥下面的提示可以看出,微信支 ...

  9. java 微信转账 ca_error_java,微信支付退款_微信支付退款接口调用证书出现错误,java,微信支付退款,ssl - phpStudy...

    微信支付退款接口调用证书出现错误 PS:代码是copy腾讯提供的demo,但运行有问题,望大拿能够帮忙解决 加载证书时间出现如下错误: java.io.IOException: DER input, ...

最新文章

  1. Quartz.NET在ASP.NET 中使用
  2. water-and-jug-problem
  3. python对excel某一列求和-96、python操作excel求和
  4. EventTrigger接管所有事件导致其他事件无法触发
  5. va_start、va_end、va_list的使用
  6. zabbix监控suse linux,SuSE 系统之部署 Zabbix 监控服务
  7. 如何使用log4j记录日志
  8. 日期天数转换c语言程序,C语言 ---计算连个日期之间的天数转换
  9. razor java,如何在Razor中声明局部变量?
  10. 正则表达式在NLP的基本应用
  11. html视频长宽代码,html插入视频,html添加视频的代码
  12. 简单学习SIPp使用手册
  13. 传感器研究NO1.陀螺仪
  14. 05使用TypeScript实现Doom3词法解析器(读书笔记:TypeScript图形渲染实战算法分析与架构设计)
  15. 《linux硬盘安装方法 》——引自 http://blog.csdn.net/rusi_lsk/
  16. android 8.0设置横幅通知,安卓微信8.0.3正式更新:新增公告横幅提醒等8大更新!...
  17. java map 队列_JavaSE-List/Map/Queue
  18. Android软件测试外文文献,软件测试中英文对照外文翻译文献
  19. “道”与“术”之关系
  20. VIL-100视频车道线实例数据集格式转换

热门文章

  1. HTML精美大转盘源码
  2. 智能小区电动车充电站方案 充满自停:避免过充,保护充电安全
  3. 03FPGA—led灯的显示(入门)
  4. KVM网络模型之:PCI Passthrough
  5. 微软的补丁为什么修复同一漏洞有两个相邻版本号的补丁以及GDR和QFE的区别
  6. HDU-4044 GeoDefense【树状dp+01背包】
  7. 计算机毕设之基于Java的超级马里奥游戏设计与实现
  8. 安全公司爆料:多家国产品牌手机被预装间谍应用!
  9. uniapp image高度不自适应
  10. 遗传算法(四)MATLAB GA工具箱使用 附解TSP问题