微信訊息體簽名及加解密功能詳細解析以及.net實現

傑克.陳發表於2015-02-02
原文:微信訊息體簽名及加解密功能詳細解析以及.net實現

前言

微信訊息體簽名及加密功能已上線,明文傳輸確實存在安全風險,鑑於微信的使用者範圍使用之廣泛,必定會成為眾矢之的。所以大家還是儘快接入安全模式為好。仔細閱讀官方接入指南,發現這次安全升級只是涉及到使用者在微信對話視窗中與公眾好訊息互動,所以此次升級還是比較簡單的。下面為大家一一道來。

 

一、功能解析

微信訊息體簽名及加密功能已上線,出於安全考慮,強烈建議您儘快接入訊息加密功能,消除安全風險。詳見公告。公眾平臺介面除錯工具已經全面支援訊息體加密功能的線上除錯,可以在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_typemsg_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演算法的加解密金鑰。然後儲存即可。
 
 


相關文章