首頁  >  文章  >  微信小程式  >  微信存取探密—加密訊息的處理

微信存取探密—加密訊息的處理

高洛峰
高洛峰原創
2017-03-06 10:18:422701瀏覽

在上一篇文章中,介紹了被動回調介面的抽象資料層次,並實作了一個高效的實體與XML互轉的基礎功能。細心的開發者在初次修改公眾號的基本配置時會發現一個名為「訊息加解密方式」的選項。展開後可供選擇的值為:「明文模式」(預設)、「相容模式」和「安全模式(建議)」。那麼這個安全模式又是什麼呢?如何適配安全模式呢?帶著這些問題,來進入微信接取的第三次探秘之旅。

可惡的流量劫持在文章的一開始,先給大家看兩張處於正常使用中的手機螢幕截圖:

微信存取探密—加密訊息的處理

在螢幕的右下角你會看到都有個綠色的水球顯示,這與要顯示的畫面格格不入,很明顯不是設計者為之。點開水球,顯示的是目前通訊套餐中剩餘的流量詳情。

從家庭區域網路到Internet再到IDC機房內網,我們的資料連結充滿了轉送的過程。我們的資料在經過任何一台設備的轉發時都有可能被其持久化保存起來。你的辦公室內網一定安全嗎?潛伏在你身邊的駭客,透過設定區域網路內某個網路卡為混雜模式(Promiscuous Mode)可以將區域網路中的所有資料都接收一份。可能你並不能發現什麼,然而你的私有資料已經被別人竊取。

使用安全模式保護使用者隱私

當啟用安全模式之後,被動回呼介面接收到的訊息就產生了很大的變化,形式如下所示:

<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位元組隨機數,該部分資料無實際意義,可用於後續返回加密訊息時作為隨機數的填充資料。

安全模式的簽章驗證方法

微信的被動回呼介面其實是一個HTTP POST請求,我們都知道HTTP請求分為請求頭和請求體。微信巧妙地將加密的XML資料放在了請求體,將驗證簽章時使用的參數放入了請求頭。

POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6×tamp=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>

簽名產生的過程:

微信存取探密—加密訊息的處理

透過上述計算,現在得出了目前加密訊息的簽章calculated_sign,然後從請求頭中取得參數msg_signature ,如果calculated_sign和msg_signature相同,則表示訊息沒有被竄改。這種簽章策略利用的數學難題有: 
1. SHA1摘要演算法對全部資料進行了計算,有任何改動最終的摘要都會改變; 
2. Token是事先設定好的,在傳輸過程中並不包含,無從破解; 
3. 時間戳記和隨機字元的引入,使得即便明文相同,每一次加密密文都有不同,給破解AES加密增加難度

簽名驗證成功之後就可以放心使用解密後的明文了。明文的格式和先前文章介紹的格式一致,因此解密後的業務處理邏輯可以重複使用。

作為安全模式的回應,回傳的XML格式也應該是加密的,整個加密過程與解密過程方向相反,這裡就不再贅述了。

更多微信存取探密—加密訊息的處理相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn