前言
微信消息体签名及加密功能已上线,明文传输确实存在安全风险,鉴于微信的用户范围使用之广泛,必定会成为众矢之的。所以大家还是尽快接入安全模式为好。仔细阅读官方接入指南,发现这次安全升级只是涉及到用户在微信对话窗口中与公众好消息交互,所以此次升级还是比较简单的。下面为大家一一道来。
一、功能解析
微信消息体签名及加密功能已上线,出于安全考虑,强烈建议您尽快接入消息加密功能,消除安全风险。详见公告。公众平台接口调试工具已经全面支持消息体加密功能的在线调试,可以在http://mp.weixin.qq.com/debug,“接口类型”选择消息接口调试,并在“加密调试”选择兼容模式或者安全模式,在线调试消息体加解密功能。
目前,公众平台推送给公众账号的基础消息和公众账号回复的响应消息存在一定程度的安全风险,为了更好的保护用户和公众账号的信息安全,公众平台将对信息安全进行升级,升级内容如下:
1. 新增消息体签名验证,用于公众平台和公众账号验证消息体正确性
2. 针对推送给微信公众账号的普通消息和事件消息,以及推送给设备公众账号的设备消息进行加密
3. 公众账号对密文消息的回复也要求加密
也就是说在安全模式下,服务器要对用户回复的消息进行解密,对公众号回复给用户的消息需要加密。
公众号直接调用微信服务器的接口除外,因为已经全部使用https协议。
我们官方demo(Deepleo.Web项目就是demo),里面 Controllers/WeixinController 就是接受用户消息并回复消息。
二、公众号接入步骤
1.下载C#版本的官方加密解密文件。
这部分我已经下载到SDK中,大家不用理会。详见:https://github.com/night-king/we ... in.SDK/Cryptography
2.修改WeixinController的Post方法
在安全模式下,微信服务器POST过来的request只是增加了2个参数,encrypt_type和msg_signature(注意不是signature)所以修改起来相对简单。
encrypt_type=aes时,表示微信已经为公众号启用安全模式了。msg_signature是微信给予我们用于的解密签名串,仅仅用于解密,加密不需要msg_signature。
下面的代码就顺理成章啦。
/// <summary> /// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。
/// 完整版:https://github.com/night-king/we ... WeixinController.cs /// </summary> [HttpPost] [ActionName("Index")] public ActionResult Post(string signature, string timestamp, string nonce, string echostr) { WeixinMessage message = null; var safeMode = Request.QueryString.Get("encrypt_type") == "aes"; using (var streamReader = new StreamReader(Request.InputStream)) { var decryptMsg = string.Empty; var msg = streamReader.ReadToEnd(); #region 解密 if (safeMode) { var msg_signature = Request.QueryString.Get("msg_signature"); var wxBizMsgCrypt = new WXBizMsgCrypt(WeixinConfig.Token, WeixinConfig.EncodingAESKey, WeixinConfig.AppID); var ret = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decryptMsg); if (ret != 0)//解密失败 { //TODO:开发者解密失败的业务处理逻辑 //注意:本demo用log4net记录此信息,你可以用其他方法 LogWriter.Default.WriteError(string.Format("decrypt message return {0}, request body {1}", ret, msg)); } } else { decryptMsg = msg; } #endregion message = AcceptMessageAPI.Parse(decryptMsg); } var response = new WeixinExecutor().Execute(message); var encryptMsg = string.Empty; #region 加密 if (safeMode) { var msg_signature = Request.QueryString.Get("msg_signature"); var wxBizMsgCrypt = new WXBizMsgCrypt(WeixinConfig.Token, WeixinConfig.EncodingAESKey, WeixinConfig.AppID); var ret = wxBizMsgCrypt.EncryptMsg(response, timestamp, nonce, ref encryptMsg); if (ret != 0)//加密失败 { //TODO:开发者加密失败的业务处理逻辑 LogWriter.Default.WriteError(string.Format("encrypt message return {0}, response body {1}", ret, response)); } } else { encryptMsg = response; } #endregion return new ContentResult { Content = encryptMsg, ContentType = "text/xml", ContentEncoding = System.Text.UTF8Encoding.UTF8 }; }
注意:WXBizMsgCrypt为官方提供的C#版本的AES加密解密类,你可以在这里下载这些文件。
详见:https://github.com/night-king/we ... WeixinController.cs
3.微信公众平台后台设置
登录微信公众平台后台,点击开发者中心,修改“消息加密方式”为“安全模式”。
因为兼容模式传输的消息体为明文模式的3倍,安全模式和明文模式不相上下,所以我个人不建议使用兼容模式,官方弄个兼容模式也是给大家平滑安全的从明文模式过渡到安全模式用的。
这里还需要设置EncodingAESKey,也就是AES算法的加解密密钥。然后保存即可。