QQ小程序 開放數(shù)據(jù)校驗和解密

2020-07-15 16:32 更新

小程序可以通過各種前端接口獲取QQ提供的開放數(shù)據(jù)??紤]到開發(fā)者服務器也需要獲取這些開放數(shù)據(jù),QQ會對這些數(shù)據(jù)做簽名和加密處理。開發(fā)者后臺拿到開放數(shù)據(jù)后可以對數(shù)據(jù)進行校驗簽名和解密,來保證數(shù)據(jù)不被篡改。

簽名校驗以及數(shù)據(jù)加解密涉及用戶的會話密鑰 session_key。 開發(fā)者應該事先通過 qq.login 登錄流程獲取會話密鑰 session_key 并保存在服務器。為了數(shù)據(jù)不被篡改,開發(fā)者不應該把 session_key 傳到小程序客戶端等服務器外的環(huán)境。

數(shù)據(jù)簽名校驗

為了確保開放接口返回用戶數(shù)據(jù)的安全性,QQ會對明文數(shù)據(jù)進行簽名。開發(fā)者可以根據(jù)業(yè)務需要對數(shù)據(jù)包進行簽名校驗,確保數(shù)據(jù)的完整性。

  1. 通過調(diào)用接口(如 qq.getUserInfo獲取數(shù)據(jù)時,接口會同時返回 rawData、signature,其中 signature = sha1( rawData + session_key )

  2. 開發(fā)者將 signature、rawData 發(fā)送到開發(fā)者服務器進行校驗。服務器利用用戶對應的 session_key 使用相同的算法計算出簽名 signature2 ,比對 signature 與 signature2 即可校驗數(shù)據(jù)的完整性。

如 qq.getUserInfo的數(shù)據(jù)校驗:

接口返回的rawData:

{
  "nickName": "Band",
  "gender": 1,
  "language": "zh_CN",
  "city": "Guangzhou",
  "province": "Guangdong",
  "country": "CN",
  "avatarUrl": "http://qq.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"
}

用戶的 session-key:

HyVFkGl5F5OQWJZZaNzBBg==

1

用于簽名的字符串為:

{"nickName":"Band","gender":1,"language":"zh\_CN","city":"Guangzhou","province":"Guangdong","country":"CN","avatarUrl":"http://qq.qlogo.cn/mmopen/vi\_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"}HyVFkGl5F5OQWJZZaNzBBg==

1

使用sha1得到的結果為

75e81ceda165f4ffa64f4068af58c64b8f54b88c

1

加密數(shù)據(jù)解密算法

接口如果涉及敏感數(shù)據(jù)(如qq.getUserInfo 當中的 openId 和 unionId),接口的明文內(nèi)容將不包含這些敏感數(shù)據(jù)。開發(fā)者如需要獲取敏感數(shù)據(jù),需要對接口返回的加密數(shù)據(jù)(encryptedData) 進行對稱解密。 解密算法如下:

  1. 對稱解密使用的算法為 AES-128-CBC,數(shù)據(jù)采用PKCS#7填充。

  2. 對稱解密的目標密文為 Base64_Decode(encryptedData)。

  3. 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節(jié)。

  4. 對稱解密算法初始向量 為Base64_Decode(iv),其中iv由數(shù)據(jù)接口返回。

另外,為了應用能校驗數(shù)據(jù)的有效性,會在敏感數(shù)據(jù)加上數(shù)據(jù)水印( watermark )

watermark參數(shù)說明:

參數(shù) 類型 說明
appid String 敏感數(shù)據(jù)歸屬 appId,開發(fā)者可校驗此參數(shù)與自身 appId 是否一致
timestamp Int 敏感數(shù)據(jù)獲取的時間戳, 開發(fā)者可以用于數(shù)據(jù)時效性校驗

如接口qq.getUserInfo;敏感數(shù)據(jù)當中的 watermark:

{
  "openId": "OPENID",
  "nickName": "NICKNAME",
  "gender": GENDER,
  "city": "CITY",
  "province": "PROVINCE",
  "country": "COUNTRY",
  "avatarUrl": "AVATARURL",
  "unionId": "UNIONID",
  "watermark": {
    "appid": "APPID",
    "timestamp": TIMESTAMP
  }
}

注:

  1. 解密后得到的json數(shù)據(jù)根據(jù)需求可能會增加新的字段,舊字段不會改變和刪減,開發(fā)者需要預留足夠的空間

會話密鑰 session_key 有效性

開發(fā)者如果遇到因為 session_key 不正確而校驗簽名失敗或解密失敗,請關注下面幾個與 session_key 有關的注意事項。

  1. qq.login 調(diào)用時,用戶的 session_key 可能會被更新而致使舊 session_key 失效(刷新機制存在最短周期,如果同一個用戶短時間內(nèi)多次調(diào)用 qq.login并非每次調(diào)用都導致 session_key 刷新)。開發(fā)者應該在明確需要重新登錄時才調(diào)用qq.login及時通過 code2Session 接口更新服務器存儲的 session_key。

  2. QQ不會把 session_key 的有效期告知開發(fā)者。我們會根據(jù)用戶使用小程序的行為對 session_key 進行續(xù)期。用戶越頻繁使用小程序,session_key 有效期越長。

  3. 開發(fā)者在 session_key 失效時,可以通過重新執(zhí)行登錄流程獲取有效的 session_key。使用接口 qq.checkSession可以校驗 session_key 是否有效,從而避免小程序反復執(zhí)行登錄流程。

  4. 當開發(fā)者在實現(xiàn)自定義登錄態(tài)時,可以考慮以 session_key 有效期作為自身登錄態(tài)有效期,也可以實現(xiàn)自定義的時效性策略。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號