Resolved WeChat payment refund callback notification interface req_info AES decryption error Illegal key size or default parameters.

Wechat refund callback will report an error when decrypting req_info: Illegal key size or default parameters.

  • WeChat official document address: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10#menu1

Decryption method The
decryption steps are as follows:
(1) Decode the encrypted string A with base64 to get the encrypted string B
(2) Do md5 for the merchant key to get the 32-bit lowercase key* (key setting path: WeChat merchant platform (pay.weixin.qq) .com)–>Account Settings–>API Security–>Key Settings)
(3) Use key* to decrypt encrypted string B with AES-256-ECB (PKCS7Padding)

The solution to the error when decrypting is [the point is here]:

  1. First download jce_policy from the oracle official, mine is jdk8
  2. JDK7 download address:
    http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
    JDK8 download address:
    http://www.oracle.com/technetwork/java /javase/downloads/jce8-download-2133166.html

After downloading, we decompress the zip jce_policy, we can see two jar packages
Insert picture description here

Replace the two jar packages just downloaded in jdk and jre with the two jars in
Java\jdk1.8.0_71\jre\lib\security\ with the ones in
Java\jre1.8.0_71\lib\security\ Replace the two jars

Here is the callback code after my refund is successful:

 @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;
    }

Guess you like

Origin blog.csdn.net/m0_43413873/article/details/114385952