微信支付退款解析 對加密串 B 做 AES-256-ECB 解密(PKCS7Padding)

lizhiqiang666發表於2019-12-06

1.微信支付文件 https://pay.weixin.qq.com/wiki/doc/api/H5....

解密方式

解密步驟如下: 

(1)對加密串A做base64解碼,得到加密串B

(2)對商戶key做md5,得到32位小寫key* ( key設定路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設定-->API安全-->金鑰設定 )

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

2.

解決方法:

http://stackoverflow.com/questions/6481627...

JDK8 jar包下載地址:

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

JDK7 jar包下載地址:

http://www.oracle.com/technetwork/java/jav...

JDK6 jar包下載地址:

http://www.oracle.com/technetwork/java/jav...

把裡面的兩個jar包:local_policy.jar 和 US_export_policy.jar 替換掉原來jdk安裝目錄C:\Program Files\Java\jre6\lib\security 下的兩個jar包接可以了

3.demo示例

package encode;

import java.security.MessageDigest;

public class MD5 {
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 轉換位元組陣列為16進位制字串
     * @param b 位元組陣列
     * @return 16進位制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }

    /**
     * 轉換byte到16進位制
     * @param b 要轉換的byte
     * @return 16進位制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * MD5編碼
     * @param origin 原始字串
     * @return 經過MD5加密之後的結果
     */
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

    public static void main(String[] args) {
        System.out.println("111"+MD5Encode("111"));
    }

}
/**
 * 
 */
package encode;

import java.util.Base64;

/**
 * @author jing.huang
 * @function jdk8支援
 * @date 2018年1月10日
 * @version 
 */
public class Base64Util {

    public static byte[] decode(String encodedText){
        final Base64.Decoder decoder = Base64.getDecoder();
        return decoder.decode(encodedText);
    }

    public static String encode(byte[] data){
        final Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(data);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            final Base64.Decoder decoder = Base64.getDecoder();
            final Base64.Encoder encoder = Base64.getEncoder();
            final String text = "字串文字";
            final byte[] textByte = text.getBytes("UTF-8");
            //編碼
            final String encodedText = encoder.encodeToString(textByte);
            System.out.println(encodedText);
            //解碼
            System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }

//        final Base64.Decoder decoder = Base64.getDecoder();
//        final Base64.Encoder encoder = Base64.getEncoder();
//        final String text = "字串文字";
//        final byte[] textByte = text.getBytes("UTF-8");
//        //編碼
//        final String encodedText = encoder.encodeToString(textByte);
//        System.out.println(encodedText);
//        //解碼
//        System.out.println(new String(decoder.decode(encodedText), "UTF-8"));

    }

}
/**
 * 
 */
package encode;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author jing.huang
 * @function
 * @date 2018年1月10日
 * @version 
 */
public class AESUtil {
    /** 
     * 金鑰演算法 
     */  
    private static final String ALGORITHM = "AES";  
    /** 
     * 加解密演算法/工作模式/填充方式 
     */  
    private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding";  
    /** 
     * 生成key 
     */  
    private static SecretKeySpec key = new SecretKeySpec(MD5.MD5Encode("2IBtBXdrqC3kCBs4gaceL7nl2nnFadQv").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, key);  
        return Base64Util.encode(cipher.doFinal(data.getBytes()));  
    }  

    /** 
     * AES解密 
     *  
     * @param base64Data 
     * @return 
     * @throws Exception 
     */  
    public static String decryptData(String base64Data) throws Exception {  
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);  
        cipher.init(Cipher.DECRYPT_MODE, key);  
        return new String(cipher.doFinal(Base64Util.decode(base64Data)));  
    }  

    public static void main(String[] args) throws Exception {  
        //解密
//        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=";
        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==";
        String B = AESUtil.decryptData(req_info);  
        System.out.println(B);  

        //加密
        String str = "<root>"+
                "<out_refund_no><![CDATA[2531340110812300]]></out_refund_no>"+
                "<out_trade_no><![CDATA[2531340110812100]]></out_trade_no>"+
                "<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>"+
                "<refund_fee><![CDATA[1]]></refund_fee>"+
                "<refund_id><![CDATA[50000505542018011003064518841]]></refund_id>"+
                "<refund_recv_accout><![CDATA[支付使用者零錢]]></refund_recv_accout>"+
                "<refund_request_source><![CDATA[API]]></refund_request_source>"+
                "<refund_status><![CDATA[SUCCESS]]></refund_status>"+
                "<settlement_refund_fee><![CDATA[1]]></settlement_refund_fee>"+
                "<settlement_total_fee><![CDATA[1]]></settlement_total_fee>"+
                "<success_time><![CDATA[2018-01-10 10:31:24]]></success_time>"+
                "<total_fee><![CDATA[1]]></total_fee>"+
                "<transaction_id><![CDATA[4200000052201801101409025381]]></transaction_id>"+
                "</root>";
        System.out.println(encryptData(str));
    }  

}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章