微信企业号回调模式配置解说 Java Servlet+Struts2版本号

echostr校验失败解决

echostr校验失败,请您检查是否正确解密并输出明文echostr

异常java.security.InvalidKeyException:illegal Key Size 也就是echostr校验失败,请您检查是否正确解密并输出明文echostr这个错误

企业微信登陆地址http://qy.weixin.qq.com/

配置成功以后

Servlet

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 微信加密签名
String msg_signature = request.getParameter("msg_signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
// 打印请求地址
System.out.println("request=" + request.getRequestURL());
// 流
PrintWriter out = response.getWriter();
// 通过检验signature对请求进行校验。若校验成功则原样返回echostr,表示接入成功,否则接入失败
String result = null;
try {
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParamesAPI.token, ParamesAPI.encodingAESKey, ParamesAPI.corpId);
// 验证URL函数
result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);
} catch (AesException e) {
e.printStackTrace();
}
if (result == null) {
// result为空,赋予token
result = ParamesAPI.token;
}
// 拼接请求參数
String str = msg_signature + " " + timestamp + " " + nonce + " " + echostr;
// 打印參数+地址+result
System.out.println("Exception:" + result + " " + request.getRequestURL() + " " + "FourParames:" + str);
String info = "Exception:" + result + " " + request.getRequestURL() + " " + "FourParames:" + str;
log.info(info);
out.print(result);
out.close();
out = null;
}

官方回调页面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import java.io.StringReader;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;
 
public class Sample {
 
    public static void main(String[] args) throws Exception {
        String sToken = "QDG6eK";
        String sCorpID = "wx5823bf96d3bd56c7";
        String sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";
 
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
        /*
        ------------使用演示样例一:验证回调URL---------------
        *企业开启回调模式时。企业号会向验证url发送一个get请求 
        如果点击验证时,企业收到类似请求:
        * GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D 
        * HTTP/1.1 Host: qy.weixin.qq.com
 
        接收到该请求时,企业应        1.解析出Get请求的參数,包含消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),
        这一步注意作URL解码。
        2.验证消息体签名的正确性 
        3. 解密出echostr原文。将原文当作Get请求的response。返回给公众平台
        第2。3步能够用公众平台提供的库函数VerifyURL来实现。

 
        */
        // 解析出url上的參数值例如以下:
        // String sVerifyMsgSig = HttpUtils.ParseUrl("msg_signature");
        String sVerifyMsgSig = "5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3";
        // String sVerifyTimeStamp = HttpUtils.ParseUrl("timestamp");
        String sVerifyTimeStamp = "1409659589";
        // String sVerifyNonce = HttpUtils.ParseUrl("nonce");
        String sVerifyNonce = "263014780";
        // String sVerifyEchoStr = HttpUtils.ParseUrl("echostr");
        String sVerifyEchoStr = "P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ==";
        String sEchoStr; //须要返回的明文
        try {
            sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,
                    sVerifyNonce, sVerifyEchoStr);
            System.out.println("verifyurl echostr: " + sEchoStr);
            // 验证URL成功。将sEchoStr返回
            // HttpUtils.SetResponse(sEchoStr);
        catch (Exception e) {
            //验证URL失败。错误原因请查看异常
            e.printStackTrace();
        }
 
        /*
        ------------使用演示样例二:对用户回复的消息解密---------------
        用户回复消息或者点击事件响应时,企业会收到回调消息。此消息是经过公众平台加密之后的密文以post形式发送给企业,密文格式请參考官方文档
        如果企业收到公众平台的回调消息例如以下:
        POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6&timestamp=1409659813&nonce=1372623149 HTTP/1.1
        Host: qy.weixin.qq.com
        Content-Length: 613
        <xml>        <ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt>
        <AgentID><![CDATA[218]]></AgentID>
        </xml>
 
        企业收到post请求之后应该        1.解析出url上的參数。包含消息体签名(msg_signature),时间戳(timestamp)以及随机数字串(nonce)
        2.验证消息体签名的正确性。

        3.将post请求的数据进行xml解析。并将<Encrypt>标签的内容进行解密,解密出来的明文即是用户回复消息的明文,明文格式请參考官方文档
        第2。3步能够用公众平台提供的库函数DecryptMsg来实现。

        */
        // String sReqMsgSig = HttpUtils.ParseUrl("msg_signature");
        String sReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6";
        // String sReqTimeStamp = HttpUtils.ParseUrl("timestamp");
        String sReqTimeStamp = "1409659813";
        // String sReqNonce = HttpUtils.ParseUrl("nonce");
        String sReqNonce = "1372623149";
        // post请求的密文数据
        // sReqData = HttpUtils.PostData();
        String sReqData = "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt><AgentID><![CDATA[218]]></AgentID></xml>";
 
        try {
            String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);
            System.out.println("after decrypt msg: " + sMsg);
            // TODO: 解析出明文xml标签的内容进行处理
            // For example:
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(sMsg);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
 
            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Content");
            String Content = nodelist1.item(0).getTextContent();
            System.out.println("Content:" + Content);
             
        catch (Exception e) {
            // TODO
            // 解密失败,失败原因请查看异常
            e.printStackTrace();
        }
 
    /*
        ------------使用演示样例三:企业回复用户消息的加密---------------
        企业被动回复用户的消息也须要进行加密,而且拼接成密文格式的xml串。

        如果企业须要回复用户的明文例如以下:
        <xml>
        <ToUserName><![CDATA[mycreate]]></ToUserName>
        <FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName>
        <CreateTime>1348831860</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[this is a test]]></Content>
        <MsgId>1234567890123456</MsgId>
        <AgentID>128</AgentID>
        </xml>
 
        为了将此段明文回复给用户,企业应:            1.自己生成时间时间戳(timestamp),随机数字串(nonce)以便生成消息体签名。也能够直接用从公众平台的post url上解析出的相应值。

        2.将明文加密得到密文。    3.用密文,步骤1生成的timestamp,nonce和企业在公众平台设定的token生成消息体签名。            4.将密文,消息体签名,时间戳。随机数字串拼接成xml格式的字符串,发送给企业。
        以上2,3,4步能够用公众平台提供的库函数EncryptMsg来实现。

        */
        String sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";
        try{
            String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce);
            System.out.println("after encrypt sEncrytMsg: " + sEncryptMsg);
            // 加密成功
            // TODO:
            // HttpUtils.SetResponse(sEncryptMsg);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            // 加密失败
        }
 
    }
}

来重点了:echostr校验失败,请您检查是否正确解密并输出明文echostr

有可能会遇到这种错误。大家就百度搜索也找不到。

由于官方提供了解决方式。所以,细致

看官方提供的验证加密的源码是有作用的。



说明:异常java.security.InvalidKeyException:illegal Key Size的解决方式



 * 在官方站点下载JCE无限制权限策略文件(JDK7的下载地址:

 *   http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

 * 下载后解压。能够看到local_policy.jar和US_export_policy.jar以及readme.txt

 * 假设安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security文件夹下覆盖原来的文件

 * 假设安装了JDK。将两个jar文件放到%JDK_HOME%\jre\lib\security文件夹下覆盖原来文件

Struts2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    public String execute() throws Exception {
        // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        //微信加密签名
        String msg_signature = request.getParameter("msg_signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        PrintWriter out = response.getWriter();
        String result = null;
        // 请求校验
        try{
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParamesAPI.token, ParamesAPI.encodingAESKey, ParamesAPI.corpId);
            //验证URL函数
            result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);
         
            if(result==null){
                result = ParamesAPI.token;
            }else{
                out.print(result);
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("请求错误,稍后再试",e);
        }
        out.close();
        out = null;
        return null;
      }

个人微博 http://weibo.com/zxshuai319 

个人博客http://my.oschina.net/xshuai/blog 

有问题请回复本博客

sid=687095" rel="nofollow">

个人联盟http://www.bengbeng.com/?

sid=687095  

微信企业号回调模式配置解说 Java Servlet+Struts2版本号 echostr校验失败解决的更多相关文章

  1. 十分钟搞定微信企业帐号“echostr校验失败,请您检查是否正确解密并输出明文echostr”

    问题域:在这里我们只解决密文可以正确解密,但微信验证提示“echostr校验失败,请您检查是否正确解密并输出明文echostr”的问题. 干货:没有正确验证的原因是:你给微信返回的是字符串,而微信需要 ...

  2. 微信企业号C#开发配置API

    微信开发第一步 :   配置API,实现接收消息服务配置 1.在下图界面先填好内容,事件消息处理可自行选择,我这里是没处理的 2.第二步: 使用vs 进行代码的编写,以下是我的代码.LogTextHe ...

  3. 微信 回调模式 echostr校验失败,请您检查是否正确解密并输出明文echostr

  4. C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密

    在上篇随笔<C#开发微信门户及应用(19)-微信企业号的消息发送(文本.图片.文件.语音.视频.图文消息等)>介绍了有关企业号的消息发送,官方特别声明消息是不用加密发送的.但是在回调的服务 ...

  5. Target-Action回调模式

    前面的博客中提到过回调的概念,是在OC通过协议来实现的回调,和Java中的接口的回调极为相似,下面来介绍另一种方法回调模式: Target-Action回调.首先我们来从字面意思来理解一下Target ...

  6. 微信企业号开发入门(回调模式)java

    最近在开发微信企业号,刚接触时云里雾里的,在摸索过程中终于清晰了一点. 刚开始我以为订阅号.服务号.企业号的接口差不多,就一直用订阅号的教程来入门,后来才发现差的挺多的. 首先,微信企业号不像订阅号和 ...

  7. 微信企业号开发(1)WebAPI在回调模式中的URL验证

    微信回调模式的官方文档. 开发语言:C#(微信相关功能代码可以从官网下载) 首先,必须要明确几个参数,这几个参数在微信企业号中,每次调用都会使用到. 1.msg_signature:签名(已加密,加密 ...

  8. 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下载)

    最近研究了下服务号的服务器配置和企业号的回调模式.真正实现完后,觉得很简单,但一开始还是走了点弯路,所以写了个web程序,只用改下配置文件里的参数就可以直接用了.下面介绍下详细的用法以及实现步骤. 本 ...

  9. .net之微信企业号开发(三) 回调模式的接口开发

    一.前言 微信企业号应用中,有两种模式,一种是普通模式,这种模式只能进行简单网页链接,以及发送固定的消息.为了可以让企业号的用户更好的与应用交互,微信提供了回调模式,这种回调模式的可以将用户发送给微信 ...

随机推荐

  1. Docker 学习笔记(CentOS 7.1)

    基本概念 Docker 包括三个基本概念 镜像(Image) 容器(Container) 仓库(Repository)理解了这三个概念,就理解了 Docker 的整个生命周期. Docker 镜像 D ...

  2. 多校6 1010 HDU5802 Windows 10 dfs

    // 多校6 1010 HDU5802 Windows 10 // 题意:从p到q有三种操作,要么往上升只能1步,要么往下降,如果连续往下降就是2^n, // 中途停顿或者向上,下次再降的时候从1开始 ...

  3. 第二篇:基于K-近邻分类算法的约会对象智能匹配系统

    前言 假如你想到某个在线约会网站寻找约会对象,那么你很可能将该约会网站的所有用户归为三类: 1. 不喜欢的 2. 有点魅力的 3. 很有魅力的 你如何决定某个用户属于上述的哪一类呢?想必你会分析用户的 ...

  4. armv8(aarch64)linux内核中flush_dcache_all函数详细分析

    /* *  __flush_dcache_all() *  Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY( ...

  5. 搬寝室(HDU 1421 DP)

    搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  6. 织梦dedecms如何修改关键词的字数长度限制

    亲测,这个教程比较完善,百度了很多有些少步骤,或者方法根本不对,导致不成功.这个方法我亲子测试了.奏效. 首先登陆数据库后台,如phpmyadmin,找到相应的数据表dede_archives和ded ...

  7. Linux 中查看进程及资源使用情况

    top 自带的 top 命令类似于平时我们使用的任务管理器,能够列出当前系统中的进程及资源的使用情况. $ man top top - display Linux tasks 使用起来很简单,不加任何 ...

  8. python爬虫第五天

            cookie           我们访问网页是通过http协议进行的,而http协议是一个无状态协议(无法维持会话之间的状态),比如我们登录一个网站成功后访问另一个网页,那么登录状态 ...

  9. iOS 如何查看APP的jetsamEvent日志

    1.如何在iPhone上查看 设置-通用-分析-分析数据- JetsamEvent+日志 打头的系统日志. 2.如何在Mac 上查看此类分析日志 1.手机链接MAC 2.打开iTunes,点开手机图标 ...

  10. HDU - 5833: Zhu and 772002 (高斯消元-自由元)

    pro:给定N个数Xi(Xi<1e18),保证每个数的素因子小于2e3:问有多少种方案,选处一些数,使得数的乘积是完全平方数.求答案%1e9+7: N<300; sol:小于2e3的素数只 ...