在微信小程序解密 手机号,虽然一般都是由后端进行解密的。。但。。。
步骤
- 获取 session_key
- 通过button组件获取手机号信息
- 使用
Crypto插件进行解密
主要就是通过 wx.login 获取到 code,再调用code2Session 接口获取 session_key, 然后引导用户点击button获取加密数据iv和encryptedData,最后通过Crypto 插件进行解密。
第一步, 获取session_key
使用 wx.login 获取 code, 然后调用后端提供的 api 获取session_key,然后对session_key 进行存储
后端提供的api其实就是调用微信的code2Session接口,但小程序不能直接访问,微信在公众平台做了限制: 不能添加
https://api.weixin.qq.com作为服务器域名。
- session_key 在获取到加密数据后获取,导致解密手机号失败! session_key 必须在用户点击 button之前获取,因为当用户点击后微信会 根据当前的session_key加密数据。解密时,需要使用 加密时的session_key 配合。
你可能不知道的 session_key ?!
我们在 获取到用户加密数据后才去获取session_key,则很大概率解密失败。而且调用 wx.login 后会刷新session_key...所以最好将session_key 存储起来,而且session_key 的有效期是不确定的,根据用户使用小程序的频率有关。频率越高,有效期越长。
第二步, 通过引导用户点击 button 组件 获取加密数据
获取手机号 需要 认证的小程序,个人开发者不行, 查看官方解释 获取关于手机号的信息必要要通过用户点击button 才能获取, 先给button 加上
open-type='getPhoneNumber'然后再加上触发后的回调bindgetphonenumber
//wxml 代码
...
<button open-type="getPhoneNumber" bindgetphonenumber={{getPhoneNumberFn}}></button>
// js代码
....
// 获取到加密信息
getPhoneNumberFn(phoneDetail){
const { iv, encryptedData } = phoneDetail.detail;
}
第三步,使用Crypto 插件进行解密
-
首先需要添加
Crypto插件
分为两部分:-
- 在公众平台小程序账号中添加插件,步骤如下
-
- 在小程序项目根目录下的
app.json中 将 插件添加到 plugins字段中,步骤如下
公众平台小程序账号中添加插件
将插件添加到项目中
这里的Crypto会作为引入的字段名,version和provider分别是 插件的版本 和 插件开发者的 appid 可以从这里获取: crypto 详细内容 - 在小程序项目根目录下的
-
-
然后使用
Crypto插件进行解密 解密需要用到session_key,iv,encryptedData,其中iv,encryptedData是通过用户点击 button 获取。下面提供我自己写的一个解密方法
decode,使用时传入session_key,iv,encryptedData这三个参数即可,返回值info中包含解密后的内容,如果解密失败,则返回 null
const crypto = requirePlugin('Crypto');// 使用插件
/**
* 解密手机号
* @param session_key string
* @param iv string
* @param encryptedData string
* @return info 解密后的手机号
*/
export const decode = function(session_key , iv, encryptedData) {
const mode = ['CBC'];
const padding = ['Pkcs7'];
let info = null
try {
var mykey = crypto.Base64.parse(session_key)
var myiv = crypto.Base64.parse(iv)
var myEncryptedData = crypto.Base64.parse(encryptedData)
var aesCipher = crypto.Base64.stringify(myEncryptedData)
mode.map((modeItem) => {
padding.map((paddingItem) => {
const v = new crypto.AES().decrypt(aesCipher, mykey, {
iv: myiv,
mode: crypto.Mode[modeItem],
padding: crypto.Padding[paddingItem]
});
console.log(crypto.Utf8, v.toString(crypto.Utf8))
var data = JSON.parse(v.toString(crypto.Utf8))
if (data && data.watermark && data.watermark.appid === APP_ID) {
info = data;
}
console.log('解密成功的数据:',info)
})
})
} catch (e) {
console.log('decode error:', e);
//info = decode(session_key, iv,encryptedData)
}
return info;
}