談談微信公眾號開發中的信息加密(上)

今天來談談加密那些事兒。

先說微信。

微信公眾平臺的服務器配置中,有三種消息加解密方式:明文模式、兼容模式和加密模式。明文模式顧名思義,自不必說,且說兼容模式和加密模式:前者明文密文在一條消息里共存,消息長度可達到通常消息三倍,然而卻一點保密作用也沒有起到,果如文檔所說,純就是為了調試,除此之外的場合,只是掩耳盜鈴,還不如明文來得有效率。加密模式,實際上是利用 AES 和 SHA 對微信消息服務器和你的服務器之間傳遞的 XML 進行認證加密,同時保證了消息的保密性和完整性。

加密模式的具體實現細節是這樣的:微信服務器發送過來的 XML 里攜帶了密文(Encrypt字段)、時間戳(TimeStamp)、消息簽名(MsgSignature)和nonce(Nonce),而諸如 tokenappidEncodingAESKey 之類的信息是雙方之前就約定好的。

  1. 接收到微信服務器轉發過來的消息之后,首先要對消息完整性進行校驗:把 tokenTimeStamp、NonceEncrypt 等字段按字典序排序并拼接成一個字符串,然后算出該字符串的 SHA1 值,與 MsgSignature 字段進行比較,一致的話,就是認證成功,反之失敗。
  2. 認證成功之后,進入解密流程:利用 AES 解密,需要傳遞三個參數:秘鑰、加密模式和 IV (inital vector,應該翻譯成“起始向量”吧)。秘鑰是事先約定的 EncodingAESKey + '='并用 base64 解碼后的值,加密模式微信使用的是 CBC,IV 固定是秘鑰的前16字節。按說,IV 不應該多次重復使用,不過騰訊這里用了 PKCS7 算法對明文進行了位填充,或許可以避免 IV 重復使用帶來的安全隱患也未可知,我對密碼學了解不算深入,不能細究。調用 AES 算法解密之后,還要用 base64 對明文進行解碼,去掉填充字符串,從 XML 中恢復出 appid 并和約定的值進行比較,如果成功,這才算解密完成,可以進行下一步操作了。

如果要向微信服務器回復消息,就需要對消息進行加密。加密過程完全是解密過程的逆操作:先用 PKCS7 算法進行位填充,再用 AES 算法 CBC 模式對明文進行加密,然后用 base64 對密文進行編碼;再然后,用前述的 SHA1 算法計算消息簽名 MsgSignature,其中,時間戳取當前時間,nonce 可隨機生成;最后,把 EncryptMsgSignatureTimeStamp、Nonce 等字段填充進 XML ,發送給微信服務器。

微信的開發者文檔提供了多種語言的參考代碼,修修改改就能用在自己的項目上。不想自己實現也沒關系,如果你用 Python,wechat-python-sdk 這款開發包自帶了消息加解密的實現,安裝使用即可。不管你用何種方法實現,都千萬不要自己實現 AES 和 SHA 算法,必須調用經過廣泛驗證過的第三方庫(Python 的話,就是 PyCrypto),否則你自己的實現100%會存在安全隱患。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容