1. 程式人生 > 其它 >微信支付退款通知引數解密遇到的坑-附java編碼

微信支付退款通知引數解密遇到的坑-附java編碼

技術標籤:微信支付java加密解密

最近在寫微信支付退款這塊,對退款的回撥解密微信社群也沒有給出一篇解密的具體方案,通過查閱各位前輩的經驗,最終問題得到解決。
這裡總結下,後期方便查閱~

問題1:java.security.InvalidKeyException: Illegal key size or default parameters
jre自帶的加密jar包支援128位,如果需要支援256位加密、解密需要去orace下載jar包,替換jdk安裝路徑下
C:\Program Files\Java\jdk1.8.0_25\jre\lib\security 的local_policy.jar和US_export_policy.jar

微信官方給出的解密方式
解密步驟如下:
(1)對加密串A做base64解碼,得到加密串B
(2)對商戶key做md5,得到32位小寫key* ( key設定路徑:微信商戶平臺(pay.weixin.qq.com)–>賬戶設定–>API安全–>金鑰設定 )
(3)用key*對加密串B做AES-256-ECB解密(PKCS7Padding)

1.從回撥介面獲取微信返回的資料流

 request.setCharacterEncoding("UTF-8");
       DataInputStream in;
       String wxNotifyStr =
""; try { in = new DataInputStream(request.getInputStream()); byte[] dataOrigin = new byte[request.getContentLength()]; //將訊息實體的內容讀入位元組陣列dataOrigin中 in.readFully(dataOrigin); // 從位元組陣列中得到表示實體的字串 wxNotifyStr = new String(
dataOrigin); // 關閉資料流 if (null != in) { in.close(); } } catch (Exception e) { logger.error("解析資料流error={}", e); e.printStackTrace(); }

2.將wxNotifyStr轉換成實體,獲取到回撥返回的req_info
3.解密

   /**
     * 
     * @param secretInfo 微信返回的req_info的值
     * @param weChatKey 微信的key
     * @return
     * @throws Exception
     */
    public static String decryption(String secretInfo, String weChatKey) throws Exception {
        try {
        	//對商戶key做md5,得到32位小寫key* 
            SecretKeySpec key = new SecretKeySpec(DigestUtils.md5DigestAsHex(getContentBytes(weChatKey, "utf-8")).toLowerCase().getBytes(), "AES");
            //建立密碼器
            Security.addProvider(new BouncyCastleProvider());
            //用key*對加密串B做AES-256-ECB解密(PKCS7Padding)
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
            cipher.init(Cipher.DECRYPT_MODE, key);
            //返回解密後的內容
            return new String(cipher.doFinal(Base64.decode(secretInfo)));
        } catch (Exception e) {
            throw new ResultException("解密異常={}",e);
        }
    }
 private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new ResultException("MD5簽名過程中出現錯誤" + charset);
        }
    }