本文出处:http://blog.csdn.net/chaijunkun/article/details/53435972,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文

在上一篇博文中,介绍了被动回调接口的抽象数据层次,并实现了一个高效的实体与XML互转的基础功能。细心的开发者在初次修改公众号的基本配置时会发现一个名为“消息加解密方式”的选项。展开后可供选择的值为:“明文模式”(默认)、“兼容模式”和“安全模式(推荐)”。那么这个安全模式又是什么呢?如何适配安全模式呢?带着这些问题,来进入微信接入的第三次探秘之旅。

本专栏代码可在本人的CSDN代码库中下载,项目地址为:https://github.com/chaijunkun/wechat-common

可恶的流量劫持

在文章的一开始,先给大家看两幅处于正常使用中的手机屏幕截图:

在屏幕的右下角你会看到都有个绿色的水球显示,这与要显示的画面格格不入,很明显不是设计者为之。点开水球,显示的是当前通讯套餐中剩余的流量详情。

经过多方查证,它来自于北京联通。运营商强制将自己的代码注入到了当前显示的页面当中。也就是说,ISP在没经过用户同意的前提下,拦截了我们访问的内容,经过篡改后再返回给我们。例子中仅仅是流量提醒,有一些小规模的ISP甚至过分到直接私自插入广告。面对运营商级别的不法侵害,只有技术升级,采取一定的加密手段才能防止数据被非法篡改,其中HTTPS就是很好的方式。这也是为什么淘宝、京东等公司在全站实现HTTPS,

中间人监听

从家庭局域网络到Internet再到IDC机房内网,我们的数据链路充满了转发的过程。我们的数据在经过任何一台设备的转发时都有可能被其持久化保存起来。你的办公内网一定安全吗?潜伏在你身边的黑客,通过设置局域网内某个网卡为混杂模式(Promiscuous Mode)可以将局域网中的所有数据都接收一份。可能你并不能发现什么,然而你的私有数据已经被别人窃取。

使用安全模式保护用户隐私

微信的被动回调接口提供了一套基于消息加密的防范措施,来抵御这些我们面临的众多安全威胁。这里请注意,如果你提供的回调地址是https协议的,那么开启明文模式即可,因为整个传输链路层对你来说已经是安全的了。

安全模式的回调数据格式

当启用安全模式之后,被动回调接口接收到的消息就产生了很大的变化,形式如下所示:

<xml><ToUserName><![CDATA[gh_38a2de904e09]]></ToUserName><Encrypt><![CDATA[i7b8ccNA9OWDhau/F26aUWKFJ6Jd0imsDQIFPSdSfAg8mHT7rL0kIWSVpcqf6/dVSoOQOQK4T/CS3w96j4k3qcg89M6xn2RGZBs+9JkrsdRig5yhcia1B59akWb1t9QdutXqnl4edAqtXEh8SIs+N2HkOTTVldtOUHpdwLqRYuC4F6ejUoXui4xKuc3oyODR9edfL+xzZ7JfMJ1KUNF/YBJMj/Ba9y/CLLYmdFYOtCMH7tMUz8h+S0XKkHKN6r0ELLCIZJ9+PPlHZcfSGhwMLUeRF1nMIjXGEKHkI0uMcruh7wD96lMU/RFgJDjAk26xbmUYfa3l+34p+txw4R8iD3Q58S8Yekiy3lUsbk+C6eDeefGs1ck23BQ8xWU3AReWH2dEsY6SYIkb3ANeyJmcoIKZfpc/31njp0KcHAxL1Lk=]]></Encrypt>
</xml>

可以看出,明文部分保留了该消息的公众号原始ID:gh_38a2de904e09,其余部分均为加密文本(这种结构可以使得同一个后台系统,接入多个公众号,再利用每个公众号的设置进行分别解密)。由于加密结构在官方文档(http://qydev.weixin.qq.com/wiki/index.php?title=加解密库下载与返回码)中并没有明确的阐述,这里就给大家详细地说明一下。

文本密文字节密文字节数据16字节随机数4字节内容长度标识明文数据appIdBase64解码AES解密提取提取得到明文长度n从长度标识后读取n字节,UTF-8编码记录明文结束点m从明文结束点m读到末尾,UTF-8编码文本密文字节密文字节数据16字节随机数4字节内容长度标识明文数据appId

如果读者以前开发过网络协议应该很容易理解这个结构,典型的不定长消息。一定会有一个标识来指明不定长区域的长度,读取时以该值为准,在定长数据之后读取若干字节。在结构的开头,有16字节随机数,该部分数据无实际意义,可用于后续返回加密消息时作为随机数的填充数据。

安全模式的签名验证方法

微信的被动回调接口实际上是一个HTTP POST请求,我们都知道HTTP请求分为请求头和请求体。微信巧妙地将加密的XML数据放在了请求体,将验证签名时使用的参数放入了请求头。

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>
</xml>

签名生成的过程

接入配置请求时间戳随机字符回调加密XMLToken参数收集容器拼接字符串签名从头部获取从头部获取从请求体获取读取装入装入装入装入按字典序排序取SHA1摘要接入配置请求时间戳随机字符回调加密XMLToken参数收集容器拼接字符串签名

通过上述计算,现在得出了当前加密消息的签名calculated_sign,然后从请求头中获取参数msg_signature,如果calculated_sign和msg_signature相同,则说明消息没有被篡改过。这种签名策略利用的数学难题有:

  1. SHA1摘要算法对全部数据进行了计算,有任何改动最终的摘要都会发生变化;
  2. Token是事先设置好的,在传输过程中并不包含,无从破解;
  3. 时间戳和随机字符的引入,使得即便明文相同,每一次加密密文都有不同,给破解AES加密增加难度

签名验证成功之后就可以放心地使用解密后的明文了。明文的格式和之前文章中介绍的格式一致,因此解密后的业务处理逻辑可以复用。

作为安全模式的应答,返回的XML格式也应该是加密的,整个加密过程与解密过程方向相反,这里就不再赘述了。

2017年5月26日补充:微信的加密消息核心使用AES方式加密。在生产环境中,由于解密消息超过了JDK默认的安全限制值,解密时会抛出异常java.security.InvalidKeyException:illegal Key Size。解决该问题可以在官方网站下载JCE无限制权限策略文件:
a.如果使用的是JDK7:下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
b.如果使用的是JDK8:下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件,如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。

微信接入探秘(三)——加密消息的处理相关推荐

  1. 微信接入探秘(五)——万事俱备,只欠架构(API篇)

    本文出处:http://blog.csdn.net/chaijunkun/article/details/53504856,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议 ...

  2. 微信接入探秘(一)——从零认识微信接口

    本文出处:http://blog.csdn.net/chaijunkun/article/details/53385088,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议 ...

  3. 微信接入探秘(二)——懒人的OXM之路

    本文出处:http://blog.csdn.net/chaijunkun/article/details/53396765,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议 ...

  4. JAVA实现 springMVC方式的微信接入、实现消息自动回复

    前段时间小忙了一阵,微信公众号的开发,从零开始看文档,踩了不少坑,也算是熬过来了,最近考虑做一些总结,方便以后再开发的时候回顾,也给正在做相关项目的同学做个参考. 思路 微信接入:用户消息和开发者需要 ...

  5. Nodejs 微信加密消息开发

    最近在做微信接入,在采用明文消息与微信服务器进行通信时,毫无压力,改成密文后,微信提供了各种语言版本的demo,but 没有nodejs.(复制一下,语文偏科,凑字数). 做微信加密消息主要下面几个方 ...

  6. 企业微信加密消息体_加解密方案说明

    [TOC] 概述 企业微信在推送消息给企业时,会对消息内容做AES加密,以XML格式POST到企业应用的URL上. 企业在被动响应时,也需要对数据加密,以XML格式返回给企业微信. 本章节即是对加解密 ...

  7. 接入微信小程序客服消息推送

    微信小程序客服消息推送接入 这两天弄一个客服的消息推送,这里必须吐槽一下,按我以往接微信的东西的感觉这块估计也要踩坑的,而且众所周知微信的文档很坑的也乱.(吐槽一下) 小程序的配置设置: URL(服务 ...

  8. 使用微信小程序客服消息上的一些注意事项!小程序客服消息按钮,接入及消息接收

    本文分为四部分,为大家介绍一下,小程序客服消息上的一些解决方案 1.增加小程序客服按钮 2.实现客服会话(绑定客服人员,消息推送配置) 3.如何实现小程序客服智能消息(自动回复等) 4.用手机回复小程 ...

  9. Java微信公众平台开发(三)--接收消息的分类及实体的创建

    转自:http://www.cuiyongzhi.com/post/41.html 前面一篇有说道应用服务器和腾讯服务器是通过消息进行通讯的,并简单介绍了微信端post的消息类型,这里我们将建立消息实 ...

最新文章

  1. 深度学习在视觉搜索和匹配中的应用
  2. python三级字典_python_三级字典
  3. FFT快速傅立叶变换
  4. Poj 1011 UVA - 307 Sticks
  5. php扩展返回字符数组,PHP扩展之数组字符串处理
  6. React 组件间传值的几种情形
  7. php oauth 扩展,PHP扩展之Web服务(一)——OAuth
  8. 拿来即用的 Python LDAP 实现类
  9. 计算机应用基础网上作业题第二章,计算机应用基础网上作业题.doc
  10. 关于JSF Converter转换器的知识点
  11. python中断言方法举例说明_Python中断言Assertion的一些改进方案
  12. 新手SEO优化原创与伪原创
  13. Java验证输入邮箱格式是否正确
  14. 8086-逻辑运算指令
  15. 输入邮箱判断邮箱是否合法
  16. 高阶人工智能时代的畅想
  17. 英语宾语从句 引导词的选择
  18. VUE3中 v-for指令用法,列表循环
  19. 东北大学计算机难度,东北大学考研难吗
  20. Cannot launch SDK manager

热门文章

  1. java Date(日期类)和Calenda(日历类)
  2. 乘性散斑噪声理论及其仿真实例分析-Matlab源代码
  3. keil设置背景颜色(护眼)
  4. 合作式智能运输系统-车用通信系统应用层及应用数据交互标准
  5. 微信小程序公司开发前必读
  6. Springboot毕设项目二手交易平台n30e8(java+VUE+Mybatis+Maven+Mysql)
  7. 年终总结—自律给我自由
  8. Qt:qApp的使用
  9. APS期刊投稿准备: REVTex格式
  10. 审稿人给出的论文写作建议