微信企業(yè)號開發(fā)之加密方案與全局返回碼說明
本文包含了企業(yè)號回調(diào)企業(yè)時加解密的詳細方案、庫和示例代碼的下載,以及企業(yè)號api接口返回的錯誤碼。
一、關(guān)于加解密方案的詳細說明
1、術(shù)語及說明
開啟回調(diào)模式時,有以下術(shù)語需要了解:
1)msg_signature是簽名,用于驗證調(diào)用者的合法性
2)EncodingAESKey用于消息體的加密,長度固定為43個字符,從a-z, A-Z, 0-9共62個字符中選取,是AESKey的Base64編碼。解碼后即為32字節(jié)長的AESKey
3)AESKey=Base64_Decode(EncodingAESKey + “=”),是AES算法的密鑰,長度為32字節(jié)。AES采用CBC模式,數(shù)據(jù)采用PKCS#7填充;IV初始向量大小為16字節(jié),取AESKey前16字節(jié)。具體詳見:http://tools.ietf.org/html/rfc2315
4)msg為消息體明文,格式為XML
5)msg_encrypt = Base64_Encode( AES_Encrypt[random(16B) + msg_len(4B) + msg + $CorpID] ),是對明文消息msg加密處理后的Base64編碼
2、消息體簽名
為了驗證調(diào)用者的合法性,微信在回調(diào)url中增加了消息簽名,以參數(shù)msg_signature標識,企業(yè)需要驗證此參數(shù)的正確性后再解密。驗證步驟:
1)企業(yè)計算簽名:dev_msg_signature=sha1(sort(Token、timestamp、nonce、msg_encrypt))。sort的含義是將參數(shù)按照字母字典排序,然后從小到大拼接成一個字符串
2)比較dev_msg_signature和msg_signature是否相等,相等則表示驗證通過。
3、加解密方案說明
- 對明文msg加密的過程如下:
msg_encrypt = Base64_Encode( AES_Encrypt[random(16B) + msg_len(4B) + msg + $CorpID] )
AES加密的buf由16個字節(jié)的隨機字符串、4個字節(jié)的msg長度、明文msg和$CorpID組成。其中msg_len為msg的字節(jié)數(shù),網(wǎng)絡(luò) 字節(jié)序;$CorpID為企業(yè)號的CorpID。經(jīng)AESKey加密后,再進行Base64編碼,即獲得密文msg_encrypt。
- 對應(yīng)于加密方案,解密方案如下:
1)對密文BASE64解碼:aes_msg=Base64_Decode(msg_encrypt)
2)使用AESKey做AES解密:rand_msg=AES_Decrypt(aes_msg)
3)驗證解密后$CorpID、msg_len
4)去掉rand_msg頭部的16個隨機字節(jié),4個字節(jié)的msg_len,和尾部的$CorpID即為最終的消息體原文msg。
#p#
二、加解密庫下載和返回碼
1、加解密庫的返回碼
返回碼 | 說明 |
---|---|
0 | 請求成功 |
-40001 | 簽名驗證錯誤 |
-40002 | xml解析失敗 |
-40003 | sha加密生成簽名失敗 |
-40004 | AESKey 非法 |
-40005 | corpid 校驗錯誤 |
-40006 | AES 加密失敗 |
-40007 | AES 解密失敗 |
-40008 | 解密后得到的buffer非法 |
-40009 | base64加密失敗 |
-40010 | base64解密失敗 |
-40011 | 生成xml失敗 |
2、加解密庫下載及示例
注意事項:
1)WXBizMsgCrypt.h聲明了WXBizMsgCrypt類,提供用戶接入企業(yè)微信的三個接口。WXBizMsgCrypt.cpp文件提供了三個接口的實現(xiàn)。Sample.cpp文件提供了如何使用這三個接口的示例。
2)WXBizMsgCrypt類封裝了VerifyURL, DecryptMsg, EncryptMsg三個接口,分別用于開發(fā)者驗證回調(diào)url,收到用戶回復消息的解密以及開發(fā)者回復消息的加密過程。使用方法可以參考Sample.cpp文件。
3)加解密協(xié)議請參考企業(yè)微信官方文檔。
4)加解密過程使用了開源的openssl和tinyxml2庫,請開發(fā)者自行安裝之后使用。
*openssl的版本號是openssl-1.0.1h,http://www.openssl.org/
*tinyxml2的版本號是tinyxml2-2.1.0,https://github.com/leethomason/tinyxml2
注意事項:
1)WXBizMsgCrypt.py文件封裝了WXBizMsgCrypt接口類,提供了用戶接入企業(yè)微信的三個接口,Sample.py文件提供了如何使用這三個接口的示例,ierror.py提供了錯誤碼。
2)WXBizMsgCrypt封裝了VerifyURL, DecryptMsg, EncryptMsg三個接口,分別用于開發(fā)者驗證回調(diào)url、接收消息的解密以及開發(fā)者回復消息的加密過程。使用方法可以參考Sample.py文件。
3)本代碼用到了pycrypto第三方庫,請開發(fā)者自行安裝此庫再使用。
注意事項:
1)WXBizMsgCrypt.php文件提供了WXBizMsgCrypt類的實現(xiàn),是用戶接入企業(yè)微信的接口類。Sample.php提供了 示例以供開發(fā)者參考。errorCode.php, pkcs7Encoder.php, sha1.php, xmlparse.php文件是實現(xiàn)這個類的輔助類,開發(fā)者無須關(guān)心其具體實現(xiàn)。
2)WXBizMsgCrypt類封裝了VerifyURL, DecryptMsg, EncryptMsg三個接口,分別用于開發(fā)者驗證回調(diào)url、接收消息的解密以及開發(fā)者回復消息的加密過程。使用方法可以參考Sample.php文件。
注意事項:
1)com\qq\weixin\mp\aes目錄下是用戶需要用到的接入企業(yè)微信的接口,其中WXBizMsgCrypt.java文件提供的 WXBizMsgCrypt類封裝了用戶接入企業(yè)微信的三個接口,其它的類文件用戶用于實現(xiàn)加解密,用戶無須關(guān)心。sample.java文件提供了接口 的使用示例。
2)WXBizMsgCrypt封裝了VerifyURL, DecryptMsg, EncryptMsg三個接口,分別用于開發(fā)者驗證回調(diào)url、接收消息的解密以及開發(fā)者回復消息的加密過程。使用方法可以參考Sample.java文件。
3)請開發(fā)者使用jdk1.7以上的版本。針對org.apache.commons.codec.binary.Base64,需要導入jar包commons-codec-1.9(或comm ons-codec-1.8等其他版本),我們有提供,官方下載地址:
http://commons.apache.org/proper/commons-codec/download_codec.cgi
4)異常java.security.InvalidKeyException:illegal Key Size的解決方案:
在官方網(wǎng)站下載JCE無限制權(quán)限策略文件(JDK7的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
下載后解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。如果安裝了JRE, 將兩個jar文件放到%JRE_HOME% \lib\security目錄下覆蓋原來的文件,如果安裝了JDK,將兩個jar文件放到%JDK_HOME%\jre\lib\security目錄 下覆蓋原來文件。
注意事項:
1)Cryptography.cs文件封裝了AES加解密過程,用戶無須關(guān)心具體實現(xiàn)。WXBizMsgCrypt.cs文件提供了用戶接入企業(yè)微信的三個接口,Sample.cs文件提供了如何使用這三個接口的示例。
2)WXBizMsgCrypt.cs封裝了VerifyURL, DecryptMsg, EncryptMsg三個接口,分別用于開發(fā)者驗證回調(diào)url、接收消息的解密以及開發(fā)者回復消息的加密過程。使用方法可以參考Sample.cs文件。
#p#
三、全局返回碼說明
企業(yè)號每次調(diào)用接口時,可能獲得正確或錯誤的返回碼,企業(yè)可以根據(jù)返回碼信息調(diào)試接口,排查錯誤。
全局返回碼說明如下:
返回碼 | 說明 |
---|---|
-1 | 系統(tǒng)繁忙 |
0 | 請求成功 |
40001 | 獲取access_token時Secret錯誤,或者access_token無效 |
40002 | 不合法的憑證類型 |
40003 | 不合法的UserID |
40004 | 不合法的媒體文件類型 |
40005 | 不合法的文件類型 |
40006 | 不合法的文件大小 |
40007 | 不合法的媒體文件id |
40008 | 不合法的消息類型 |
40013 | 不合法的corpid |
40014 | 不合法的access_token |
40015 | 不合法的菜單類型 |
40016 | 不合法的按鈕個數(shù) |
40017 | 不合法的按鈕類型 |
40018 | 不合法的按鈕名字長度 |
40019 | 不合法的按鈕KEY長度 |
40020 | 不合法的按鈕URL長度 |
40021 | 不合法的菜單版本號 |
40022 | 不合法的子菜單級數(shù) |
40023 | 不合法的子菜單按鈕個數(shù) |
40024 | 不合法的子菜單按鈕類型 |
40025 | 不合法的子菜單按鈕名字長度 |
40026 | 不合法的子菜單按鈕KEY長度 |
40027 | 不合法的子菜單按鈕URL長度 |
40028 | 不合法的自定義菜單使用員工 |
40029 | 不合法的oauth_code |
40031 | 不合法的UserID列表 |
40032 | 不合法的UserID列表長度 |
40033 | 不合法的請求字符,不能包含\uxxxx格式的字符 |
40035 | 不合法的參數(shù) |
40038 | 不合法的請求格式 |
40039 | 不合法的URL長度 |
40040 | 不合法的插件token |
40041 | 不合法的插件id |
40042 | 不合法的插件會話 |
40048 | url中包含不合法domain |
40054 | 不合法的子菜單url域名 |
40055 | 不合法的按鈕url域名 |
40056 | 不合法的agentid |
40057 | 不合法的callbackurl |
40058 | 不合法的紅包參數(shù) |
40059 | 不合法的上報地理位置標志位 |
40060 | 設(shè)置上報地理位置標志位時沒有設(shè)置callbackurl |
40061 | 設(shè)置應(yīng)用頭像失敗 |
40062 | 不合法的應(yīng)用模式 |
40063 | 紅包參數(shù)為空 |
40064 | 管理組名字已存在 |
40065 | 不合法的管理組名字長度 |
40066 | 不合法的部門列表 |
40067 | 標題長度不合法 |
40068 | 不合法的標簽ID |
40069 | 不合法的標簽ID列表 |
40070 | 列表中所有標簽(用戶)ID都不合法 |
40071 | 不合法的標簽名字,標簽名字已經(jīng)存在 |
40072 | 不合法的標簽名字長度 |
40073 | 不合法的openid |
40074 | news消息不支持指定為高保密消息 |
41001 | 缺少access_token參數(shù) |
41002 | 缺少corpid參數(shù) |
41003 | 缺少refresh_token參數(shù) |
41004 | 缺少secret參數(shù) |
41005 | 缺少多媒體文件數(shù)據(jù) |
41006 | 缺少media_id參數(shù) |
41007 | 缺少子菜單數(shù)據(jù) |
41008 | 缺少oauth code |
41009 | 缺少UserID |
41010 | 缺少url |
41011 | 缺少agentid |
41012 | 缺少應(yīng)用頭像mediaid |
41013 | 缺少應(yīng)用名字 |
41014 | 缺少應(yīng)用描述 |
41015 | 缺少Content |
41016 | 缺少標題 |
41017 | 缺少標簽ID |
41018 | 缺少標簽名字 |
42001 | access_token超時 |
42002 | refresh_token超時 |
42003 | oauth_code超時 |
42004 | 插件token超時 |
43001 | 需要GET請求 |
43002 | 需要POST請求 |
43003 | 需要HTTPS |
43004 | 需要接收者關(guān)注 |
43005 | 需要好友關(guān)系 |
43006 | 需要訂閱 |
43007 | 需要授權(quán) |
43008 | 需要支付授權(quán) |
43009 | 需要認證 |
43010 | 需要處于回調(diào)模式 |
43011 | 需要企業(yè)授權(quán) |
44001 | 多媒體文件為空 |
44002 | POST的數(shù)據(jù)包為空 |
44003 | 圖文消息內(nèi)容為空 |
44004 | 文本消息內(nèi)容為空 |
45001 | 多媒體文件大小超過限制 |
45002 | 消息內(nèi)容超過限制 |
45003 | 標題字段超過限制 |
45004 | 描述字段超過限制 |
45005 | 鏈接字段超過限制 |
45006 | 圖片鏈接字段超過限制 |
45007 | 語音播放時間超過限制 |
45008 | 圖文消息超過限制 |
45009 | 接口調(diào)用超過限制 |
45010 | 創(chuàng)建菜單個數(shù)超過限制 |
45015 | 回復時間超過限制 |
45016 | 系統(tǒng)分組,不允許修改 |
45017 | 分組名字過長 |
45018 | 分組數(shù)量超過上限 |
46001 | 不存在媒體數(shù)據(jù) |
46002 | 不存在的菜單版本 |
46003 | 不存在的菜單數(shù)據(jù) |
46004 | 不存在的員工 |
47001 | 解析JSON/XML內(nèi)容錯誤 |
48002 | Api禁用 |
50001 | redirect_uri未授權(quán) |
50002 | 員工不在權(quán)限范圍 |
50003 | 應(yīng)用已停用 |
50004 | 員工狀態(tài)不正確(未關(guān)注狀態(tài)) |
50005 | 企業(yè)已禁用 |
60001 | 部門長度不符合限制 |
60002 | 部門層級深度超過限制 |
60003 | 部門不存在 |
60004 | 父親部門不存在 |
60005 | 不允許刪除有成員的部門 |
60006 | 不允許刪除有子部門的部門 |
60007 | 不允許刪除根部門 |
60008 | 部門名稱已存在 |
60009 | 部門名稱含有非法字符 |
60010 | 部門存在循環(huán)關(guān)系 |
60011 | 管理員權(quán)限不足,(user/department/agent)無權(quán)限 |
60012 | 不允許刪除默認應(yīng)用 |
60013 | 不允許關(guān)閉應(yīng)用 |
60014 | 不允許開啟應(yīng)用 |
60015 | 不允許修改默認應(yīng)用可見范圍 |
60016 | 不允許刪除存在成員的標簽 |
60017 | 不允許設(shè)置企業(yè) |
60102 | UserID已存在 |
60103 | 手機號碼不合法 |
60104 | 手機號碼已存在 |
60105 | 郵箱不合法 |
60106 | 郵箱已存在 |
60107 | 微信號不合法 |
60108 | 微信號已存在 |
60109 | QQ號已存在 |
60110 | 部門個數(shù)超出限制 |
60111 | UserID不存在 |
60112 | 成員姓名不合法 |
60113 | 身份認證信息(微信號/手機/郵箱)不能同時為空 |
60114 | 性別不合法 |