本文出处: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. javascript eval和JSON之间的联系
  2. war包部署vue_又一干货实战,spring boot2:以 War 包的形式部署
  3. java biginteger string_String到BigInteger java
  4. java中的url进行编码和解码
  5. python计算器代码,Python实现两款计算器功能示例
  6. Java单例模式的双if
  7. java语音识别毕业设计,HMM的语音识别技术的毕业设计
  8. 计算机屏幕刷新频率,屏幕刷新率多少合适,教您电脑屏幕刷新率多少合适
  9. c# 计算一年有多少周
  10. 川大锦江学院吧计算机学院答辩,川大锦江学院上演跨国网上毕业论文答辩
  11. 超体分享 | 迭代思维:你感觉原地踏步,只是因为你想一步到位
  12. JAVA_SSM装饰装修公司管理系统(含论文)毕业设计【演示视频】
  13. 快速准时安全放心,顺丰黄金派送服务受认可
  14. 广告公司网站该怎么做和运营
  15. 巴黎出差及场测攻略V1.3
  16. BN、CB领投Project Galaxy(GAL),即将在CoinList公募
  17. 页面加载时就请求ajax,页面加载时发送Ajax请求
  18. 云计算基础及应用 第一章 云计算基础
  19. 2019.9.19年华为杯数模
  20. 【06月10日】A股ROE最高排名

热门文章

  1. 让你的Android Studio性感起来--Sexy Editor
  2. 使用freeSWITCH和Yate进行VoIP通话
  3. 计算机专业课英语,计算机专业课英语计算机专业课英语.doc
  4. iOS开发-面部距离识别 Vision 护眼模式 儿童防近视功能
  5. 怎样对已经装好系统的电脑进行分区
  6. MDE RCMDE
  7. 动画:面试官问我插入排序和冒泡排序哪个更牛逼?
  8. 惠普服务器ssa找不到控制卡,惠普ssacli工具使用
  9. Sql order by 数据排序 优先级问题
  10. 三菱FX1N PLC 485与三菱变频器modbus通讯