介紹
為了避免小程序與開發者後台通信時數據被截取和篡改,微信側維護了一個用户維度的可靠key,用於小程序和後台通信時進行加密和簽名。開發者可以分別通過小程序前端和微信後台提供的接口,獲取用户的加密 key來實現數據的加密和解密
使用場景
對於在小程序中調用接口時需要防止用户脱離小程序調用接口時使用,例如登錄,註冊等敏感接口時使用小程序加密網絡通道來實現數據加密傳輸
參考地址
https://developers.weixin.qq.com/miniprogram/dev/framework/op...
https://developers.weixin.qq.com/minigame/dev/api-backend/ope...
實現流程
- 小程序端使用userCryptoManager.getLatestUserKey獲取到密鑰信息,然後使用此密鑰信息 來對需要傳輸的數據進行加密,加密方式參考:https://github.com/flash1293/aes-wasm https://github.com/ricmoo/aes-js
- 後端使用internet.getUserEncryptKey獲取到密鑰信息,然後使用此密鑰對於小程序傳遞的數據進行解密
- 後端業務代碼處理完成後,將返回給用户的數據使用密鑰信息進行加密處理傳遞給小程序端
- 小程序端接收到接口傳遞的加密數據後,使用密鑰信息進行解密操作,後續進行業務處理
代碼示例
小程序端
//someAESEncryptMethod 和 someAESDEcryptMethod 分別為加解密函數,由開發者自行引入加解密庫來實現
const somedata = 'xxxxx'
const userCryptoManager = wx.getUserCryptoManager()
userCryptoManager.getLatestUserKey({
success({encryptKey, iv, version, expireTime}) {
const encryptedData = someAESEncryptMethod(encryptKey, iv, somedata)
wx.request({
data: encryptedData,
success(res) {
const decryptedData = someAESDEcryptMethod(encryptKey, iv, res.data)
console.log(decryptedData)
}
})
}
})
後端(PHP為例)
//使用easywechat拓展實現
//$code 表示用户登錄憑證,$data表示接口傳遞參數
$miniProgram = Yii::$app->wechat->miniProgram;
$code2Session = $miniProgram->auth->session($code);
if (isset($code2Session['openid'], $code2Session['session_key'])) {
$result = $miniProgram->auth->request(
'wxa/business/getuserencryptkey',
'POST',
[
'query' => [
'openid' => $code2Session['openid'],
'signature' => bin2hex(hash_hmac('sha256', '', $code2Session['session_key'], true)),
'sig_method' => 'hmac_sha256'
]
]
);
if (isset($result['errcode']) && $result['errcode'] == 0) {
$encryptKeyData = ArrayHelper::getValue($result, ['key_info_list', 0]);
$encrypt_key = $encryptKeyData['encrypt_key'];
$iv = $encryptKeyData['iv'];
$data = openssl_decrypt(base64_decode($data), 'AES-256-CBC', $encrypt_key, 0, $iv);
//業務代碼處理
......
$result = 'XXX';//返回數據
return openssl_encrypt(base64_encode($result), 'AES-256-CBC', $encrypt_key, 0, $iv)
}
}
return false;