微信企业号回调模式配置解说 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. Element-UI 笔记

    1.表单验证 官官方地址 :     https://element.eleme.cn/#/zh-CN/component/form 使用rules进行表单字段验证  https://blog.csd ...

  2. xml转换成数组array

    直接上代码,成功转换 if($data){ //返回来的是xml格式需要转换成数组再提取值,用来做更新 $startnum = strpos($data,"<xml>" ...

  3. Nginx代理配置-centos6.10版

    nginx代理配置 cd /etc/nginx/init.d vi default.conf 添加: upstream server1{ server 192.168.125.128:8100 wei ...

  4. Halcon学习笔记之支持向量机(二)

    例程:classify_halogen_bulbs.hdev 在Halcon中模式匹配最成熟最常用的方式该署支持向量机了,在本例程中展示了使用支持向量机对卤素灯的质量检测方法.通过这个案例,相信大家可 ...

  5. ES6 Template String 模板字符串

    模板字符串(Template String)是增强版的字符串,用反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量. 大家可以先看下面一段代码: $(&quo ...

  6. Caffe: gflag编译出现问题汇总

    1. 使用Unicode字符集: 出现问题 E:\CodeBase\ML\Caffe\ThirdPartySrc\gflags-master\src\gflags.cc(1340): error C2 ...

  7. HDU_5810_数学,概率,方差

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5810 大意:将n个球往m个盒子中投,每个球被投入每个盒子的概率相等,求方差. 看题解说,这是二项分布( ...

  8. Express+Nodejs 下的登录拦截实现

    Express+Nodejs 下的登录拦截实现 利用商城举例,在商城中没有登录之前,可以看商品列表.详情.登录或者注册都可以,但是购买的时候是不行的,那么这个功能在Node后台中是怎么实现的呢,这个功 ...

  9. wget 批量下载网站目录下的文件

    执行如下命令就会自动下载 http://www.iyunwei.com/docs/ 下面的所有文件: wget -nd -r -l1 --no-parent http://www.iyunwei.co ...

  10. JAVA 生成扫描条形码

    声明:转载为个人学习收藏,如有侵权,请及时联系本人删除,转载地址:https://www.cnblogs.com/MariaWang/p/10837641.html 条形码是一种可视化.机器可读的数据 ...