java 微信推送事件 安全模式微信消息體加解密

一.示例代碼下載

微信公衆平臺爲開發者提供了5種語言的示例代碼(包括C++、php、Java、Python和C#版本) 點擊下載 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1434696670

二,微信使用xml格式的消息結構,有兩種方式

1.明文模式,POST請求有signature, timestamp, nonce三個參數。它的Body爲一個XML:

<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName> 
    <CreateTime>1348831860</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[this is a test]]></Content>
    <MsgId>1234567890123456</MsgId>
</xml>
2.加密模式中,增加了兩個參數:encrypt_type 和 msg_signature 。它的Body 也變更爲:

<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <Encrypt><![CDATA[encryptData]]></Encrypt>
</xml>
其中encryptData是加密後的信息,通過我們在微信開發平臺配置的EncodingAESKey, Token, 以及自動生成的AppID,通過加密算法,可以驗證信息的真實性,並且將真實的信息,解析成如明文的格式的XML。整條信息是加密的,因此不用擔心被僞造,否則,會有風險。
三. java代碼實現

   1. 封裝了一個AuthCheck工具類

public class AuthCheck{
    public final static String Token =yourToken ;//公衆平臺上面自己填寫的Token
    public final static String EncodingAESKey = yourEncodingAESKey;//公衆平臺上面自己填寫的43位EncodingAESKey
    public final static String AppID =yourAppID;//appid(微信生成的)

    /**
     * 將加密後的原文進行解密重新封裝
     * @param request
     * @param originalXml 原xml
     * @return    重新解密後的xml
     */
    public static String  decryptMsg(HttpServletRequest request, String originalXml) {
        // 微信加密簽名 
        //String sVerifyMsgSig = request.getParameter(signature);
        String msgSignature = request.getParameter("msg_signature");
        // 時間戳
        String timestamp = request.getParameter("timestamp");
        // 隨機數
        String nonce = request.getParameter("nonce");
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(Token, EncodingAESKey, AppID);
            return pc.decryptMsg(msgSignature, timestamp, nonce, originalXml);
        } catch (AesException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 對需要回復的原文進行加密重新封裝
     * @param request
     * @param replyXml 需要回復的xml
     * @return    重新加密後的xml
     */
    public static String  encryptMsg(HttpServletRequest request,String replyXml) {
        // 時間戳
        String timestamp = request.getParameter("timestamp");
        // 隨機數
        String nonce = request.getParameter("nonce");
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(Token, EncodingAESKey, AppID);
            return pc.encryptMsg(replyXml, timestamp, nonce);
        } catch (AesException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}
2. 處理消息如下:
@Override
public void WexHandeler(HttpServletRequest request, HttpServletResponse response) throws Exception {

    try {
        String notifyData = wxPayService.getNotifyStr(request);
        logger.error("微信事件推送:" + notifyData);
        if (StringUtils.isBlank(notifyData)) {
            return;
        }
        String result ;
        String encrypt_type =request.getParameter("encrypt_type");
        //需走加解密流程
        if (StringUtils.isNotBlank(encrypt_type) && encrypt_type.equals("aes")) {

            //解密要求消息體
            String nXmlString = AuthCheck.decryptMsg(request, notifyData);
            logger.error("--nXmlString--"+nXmlString);
            //履行原處理
             String originalResult = handleEvent(nXmlString);
            logger.error("--originalResult--"+originalResult);

             result=AuthCheck.encryptMsg(request, originalResult);
            //加密回覆消息體
        } else {//不用加密
             result = handleEvent(notifyData);
        }

        logger.error("--result--"+result);
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println(result);
    } catch (Exception e) {
        logger.error("微信事件推送error:" +e.getMessage()+JSONObject.toJSONString(request.getParameterMap()));
        return ;
    }
    return;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章