当前位置:   article > 正文

微信支付退款结果通知(回调) AES-256-ECB解密 代码_微信v3 异步通知 解密

微信v3 异步通知 解密

微信支付中的退款后,微信那边需要回调。恶心的是需要我们解密。

给大家我的代码看看。

每个类都有一个主方法供大家测试用。

Base64Util
  1. package com.xz.app.util;
  2. import java.util.Base64;
  3. /**
  4. *
  5. import java.util.Base64;
  6. /**
  7. * @author jing.huang
  8. * @function jdk8支持
  9. * @date 2018年1月10日
  10. * @version
  11. */
  12. public class Base64Util {
  13. public static byte[] decode(String encodedText){
  14. final Base64.Decoder decoder = Base64.getDecoder();
  15. return decoder.decode(encodedText);
  16. }
  17. public static String encode(byte[] data){
  18. final Base64.Encoder encoder = Base64.getEncoder();
  19. return encoder.encodeToString(data);
  20. }
  21. /**
  22. * @param args
  23. */
  24. public static void main(String[] args) {
  25. try {
  26. final Base64.Decoder decoder = Base64.getDecoder();
  27. final Base64.Encoder encoder = Base64.getEncoder();
  28. final String text = "字串文字";
  29. final byte[] textByte = text.getBytes("UTF-8");
  30. //编码
  31. final String encodedText = encoder.encodeToString(textByte);
  32. System.out.println(encodedText);
  33. //解码
  34. System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. // final Base64.Decoder decoder = Base64.getDecoder();
  39. // final Base64.Encoder encoder = Base64.getEncoder();
  40. // final String text = "字串文字";
  41. // final byte[] textByte = text.getBytes("UTF-8");
  42. // //编码
  43. // final String encodedText = encoder.encodeToString(textByte);
  44. // System.out.println(encodedText);
  45. // //解码
  46. // System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
  47. }
  48. }

 

MD5
  1. package com.xz.app.util;
  2. import java.security.MessageDigest;
  3. public class MD5 {
  4. private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
  5. "8", "9", "a", "b", "c", "d", "e", "f"};
  6. /**
  7. * 转换字节数组为16进制字串
  8. * @param b 字节数组
  9. * @return 16进制字串
  10. */
  11. public static String byteArrayToHexString(byte[] b) {
  12. StringBuilder resultSb = new StringBuilder();
  13. for (byte aB : b) {
  14. resultSb.append(byteToHexString(aB));
  15. }
  16. return resultSb.toString();
  17. }
  18. /**
  19. * 转换byte到16进制
  20. * @param b 要转换的byte
  21. * @return 16进制格式
  22. */
  23. private static String byteToHexString(byte b) {
  24. int n = b;
  25. if (n < 0) {
  26. n = 256 + n;
  27. }
  28. int d1 = n / 16;
  29. int d2 = n % 16;
  30. return hexDigits[d1] + hexDigits[d2];
  31. }
  32. /**
  33. * MD5编码
  34. * @param origin 原始字符串
  35. * @return 经过MD5加密之后的结果
  36. */
  37. public static String MD5Encode(String origin) {
  38. String resultString = null;
  39. try {
  40. resultString = origin;
  41. MessageDigest md = MessageDigest.getInstance("MD5");
  42. resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46. return resultString;
  47. }
  48. public static void main(String[] args) {
  49. System.out.println("111"+MD5Encode("111"));
  50. }
  51. }

 

AESUtil
  1. /**
  2. *
  3. */
  4. package encode;
  5. import javax.crypto.Cipher;
  6. import javax.crypto.spec.SecretKeySpec;
  7. /**
  8. * @author jing.huang
  9. * @function
  10. * @date 2018年1月10日
  11. * @version
  12. */
  13. public class AESUtil {
  14. /**
  15. * 密钥算法
  16. */
  17. private static final String ALGORITHM = "AES";
  18. /**
  19. * 加解密算法/工作模式/填充方式
  20. */
  21. private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding";
  22. /**
  23. * 生成key
  24. */
  25. private static SecretKeySpec key = new SecretKeySpec(MD5.MD5Encode("2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv").toLowerCase().getBytes(), ALGORITHM);
  26. /**
  27. * AES加密
  28. *
  29. * @param data
  30. * @return
  31. * @throws Exception
  32. */
  33. public static String encryptData(String data) throws Exception {
  34. // 创建密码器
  35. Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
  36. // 初始化
  37. cipher.init(Cipher.ENCRYPT_MODE, key);
  38. return Base64Util.encode(cipher.doFinal(data.getBytes()));
  39. }
  40. /**
  41. * AES解密
  42. *
  43. * @param base64Data
  44. * @return
  45. * @throws Exception
  46. */
  47. public static String decryptData(String base64Data) throws Exception {
  48. Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
  49. cipher.init(Cipher.DECRYPT_MODE, key);
  50. return new String(cipher.doFinal(Base64Util.decode(base64Data)));
  51. }
  52. public static void main(String[] args) throws Exception {
  53. //解密
  54. // String req_info="Ih5osM/5IbPfHouVrUmwebd1yAW2Gys91jv006W1237sSi3z022KxHafLIDMrQLYiBttTadgvy2cbx6DnmwDIQ52lPWfo6pAAHt7Q9DjBIpDRQ7JsbEBlomoQP2ZkdNHnWscVYuFEVlItaSlkSlcKLdB4UwMduqDYseFsUUthz6htPeBu987zXS6dKrgIbRwOxt5RfPmk1sf0oVB2yU3UH0Ly8SzBjmN1jrh4qAaUkfH6VkeMJcsZSGchQn2VresxJTbGH++JE1UsXUF3gyYpweyxBPtHoKdaggsIONR20UKNxJYPJLnEOnfQF/Ipmk8/QmTVRK7iqfVLC9EA1Auma0AlKBjZlYqynUlF3y+E2ZzgWMUlvDHZVWDbzp/TcE0q+Ukc7yQ3HBsibDR474SPlLTkCWz1iydXzkVcLqJKamsh76Liv1a0hzu0sI3qasMAfmwU6/q7/N6quq031toO1GxqkVaxBRK7e64gSOx9ArxxVFgZ7WN+JPq2OH/pTKH8ToxHA0rtxN5+aAgZGkXiIOUiHtp4mjpRxqe34WK7C7Nr0DQyOVwsXT2TTegSgWGm34aa//ZYxHedubv2iX+E7K222lptg9IqHlMXBbwKFtKtIcal61+8ciz+sB1FBpqHchC+3whTqWv5ZANiHBzaOhbIbA/mKX2XZ6Cy0iYh+bL/8Y/Hvz/UnMGzor+2anIUeBAGRQmseL4jY+Qic46WLuEhDcarCaO4JgJSAOC+VmsdrER9TRum26PFwTQwtNpxkrKCiO9Gv36Ood5D8hXnLHUH+4nbsek8ouxkCcFXq4Us0mipB3i5ksQpt23LiJm9Ahxyvptp9Q41SytS48NXiz3IxTOqDdknowedZwAtJ/fhBlwiOHD9N+pECXuNBKLaCZcatGycr0/DPELiCF+MIRQ6V60wzaZD74TKRFULd1ljNsoQIAbuGaT40WMDY6a28jBHQ/IXnD4gvSvfeumwQzp3Q9PiPyFtF6JxH7RBRj9/lmQuQozJIPZCaCNVTBfWQOdcFaBnPLN0ZNvzjA93g6jcIxHzkXHmiGfh98vq2E=";
  55. String req_info = "m4NnwrtY0jhpDgNp65H1V/0OWMtSoTYhhY89MHbflhmnaHq9ZKjx9ABq6Jpg4SccA876HVy7J9P85NpdvCMNGInZ4fANDRE+YfZe4HeF+bbFj6JETcEFPpE9YW+bTbC0D+gl/otScJfvB2QUK7+EeBGPHN1EWX9zbr2Gw6AUaORdFk3mGxV5dtjuwWQrv5juzkXDs33Z2dUMslO+i3j0cTDHqwS4hptx2j6h2HvzgzltFbjo7nysU+4rArqJvrGW/9r18e1St9XgG21NALqixfaSmqetOR4zLVL4/+z3CEz8cg5r+/4GUOTf3XFmLCZ/wEkRQhKRNVibG0NFfiG3KnqArMJ/dheQHCd7qL+XX/ZV6tj8RLMgL7R6hOiR03Ljyikdxq9M3K9CTYgf03pHJd3geXX1LgXrLxc1flL6NW+zD3ZayGYpr1WpLsSMG7z8W5j1pme6cRj3n2+CwSFnOnOkxaFuLKoJAJIqM3gbC0eN++vY73RKphlI4zZqg6o5s3MXI6ju1yoi/ZQ+XbTg2JttsdbU0aySernKwkt0rYMf0j/Mcvo2axgHbI3w/iTm141WxHUjkQ+ga2X1pOWdGifGhSmMP8oGaA/WD5MAsK1qXX0eFvUWS/PTauCSTWq5Cmr8loA/KL3jgvB0nyR4mfccB+tPy4Ny7kzOlr/VNeb0ULf96R0AWFWCtdt8AmujAP0DYiM5FSmYLI0XRhpSDjnEbBM8+isNE1GlAVR3NzzemwQORihScovpAktbRSN/d3N+NgTjSoVDiJvCOxCs3thX9qt9iwYbA+/X/gv8lza2FZyIzwkQxGRcYl8JWKpXzNW8EWUNVnSLdHvQttDeV3CvgP/x579RGd6whyFYS6AaI0qw7oTjCFh2EHS/VzGvFuv166ZlVIJ4MNvg79O9h63ZOSE1LzVqEsVh8fDCfM2GgJ9aUdl95Djgunit4yIZOdoigR3f/BEHKrYCEham11rYohaAXs4XAXWihsV3WD5j4G/P+txvjAwujvf4HDwzHgFsmSml013U2mUiy+v4zw==";
  56. String B = AESUtil.decryptData(req_info);
  57. System.out.println(B);
  58. //加密
  59. String str = "<root>"+
  60. "<out_refund_no><![CDATA[2531340110812300]]></out_refund_no>"+
  61. "<out_trade_no><![CDATA[2531340110812100]]></out_trade_no>"+
  62. "<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>"+
  63. "<refund_fee><![CDATA[1]]></refund_fee>"+
  64. "<refund_id><![CDATA[50000505542018011003064518841]]></refund_id>"+
  65. "<refund_recv_accout><![CDATA[支付用户零钱]]></refund_recv_accout>"+
  66. "<refund_request_source><![CDATA[API]]></refund_request_source>"+
  67. "<refund_status><![CDATA[SUCCESS]]></refund_status>"+
  68. "<settlement_refund_fee><![CDATA[1]]></settlement_refund_fee>"+
  69. "<settlement_total_fee><![CDATA[1]]></settlement_total_fee>"+
  70. "<success_time><![CDATA[2018-01-10 10:31:24]]></success_time>"+
  71. "<total_fee><![CDATA[1]]></total_fee>"+
  72. "<transaction_id><![CDATA[4200000052201801101409025381]]></transaction_id>"+
  73. "</root>";
  74. System.out.println(encryptData(str));
  75. }
  76. }

注意:key要改为自己的key

 

 

  1. /**
  2. *
  3. * 微信退款回调
  4. * @param
  5. * @param
  6. */
  7. @ApiOperation(value = "微信退款回调", notes = "微信退款回调")
  8. @RequestMapping(value = "WXtrackRefunderrorrm2", method = RequestMethod.POST)
  9. @ResponseBody
  10. public void WXtrackRefunderrorrm2(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws Exception{
  11. logger.info("开始回调");
  12. InputStream inStream = httpRequest.getInputStream();
  13. ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
  14. byte[] buffer = new byte[1024];
  15. int len = 0;
  16. while ((len = inStream.read(buffer)) != -1) {
  17. outSteam.write(buffer, 0, len);
  18. }
  19. String resultxml = new String(outSteam.toByteArray(), "utf-8");
  20. Map<String, String> params = WXPayUtil.xmlToMap(resultxml);
  21. outSteam.close();
  22. inStream.close();
  23. logger.info("here");
  24. if (params.get("return_code").equals("SUCCESS")) {
  25. logger.info("退款成功0");
  26. logger.info("退款成功1");
  27. String req_info = params.get("req_info");
  28. logger.info(req_info);
  29. // String resultStr = AESUtil.decryptData(req_error);
  30. // WXPayUtil.getLogger().error("refund:解密后的字符串:" + resultStr);
  31. // Map<String, String> aesMap = WXPayUtil.xmlToMap(resultStr);
  32. String afterDecrypt=AESUtil.decryptData(req_info);
  33. logger.info(afterDecrypt);
  34. Map<String, String> aesMap = WXPayUtil.xmlToMap(afterDecrypt);
  35. logger.info("退款成功1");
  36. /** 以下为返回的加密字段: **/
  37. // 商户退款单号 是 String(64) 1.21775E+27 商户退款单号
  38. String out_refund_no = aesMap.get("out_refund_no");
  39. // 退款状态 是 String(16) SUCCESS SUCCESS-退款成功、CHANGE-退款异常、REFUNDCLOSE—退款关闭
  40. String refund_status = aesMap.get("refund_status");
  41. // 商户订单号 是 String(32) 1.21775E+27 商户系统内部的订单号
  42. String out_trade_no = aesMap.get("out_trade_no");
  43. logger.info(refund_status);
  44. logger.info(out_trade_no);
  45. logger.info(out_refund_no);
  46. if (!WXPayConstants.SUCCESS.equals(refund_status)) {
  47. //这里写业务代码
  48. logger.info("退款成功");
  49. logger.info(params);
  50. }
  51. }
  52. }

从微信那边获得req_info后对其解密,在获得你的订单号等,来进行业务操作。

 

如果不行的话。请按下面的方法操作一下。

JAVA运行环境默认不允许256位密钥的AES加解密,解决方法就是修改策略文件

在官方网站下载JCE无限制权限策略文件

    JDK7版本JCE下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

    JDK8版本JCE下载地址: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目录下覆盖原来文件

    实践:
    以JDK8为例,系统为WIN10,替换上述security文件夹下\policy\limited文件夹和\policy\unlimited文件夹里面的local_policy.jar和US_export_policy.jar这两个文件。

    若是在服务器上,则只有在security目录下有local_policy.jar和US_export_policy.jar,替换即可

感谢简书的推荐
链接:https://www.jianshu.com/p/6d3259e88b80
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/132281
推荐阅读
相关标签
  

闽ICP备14008679号