评论

微信小程序解密敏感数据,前后端实操流程

微信小程序解密敏感数据,前后端实操流程


 微信小程序解密敏感数据,前后端实操流程

本文以前后端代码实例,描述解密流程,阅读大约10分钟


01 序言:

微信小程序对用户敏感数据获取越来越严格,很多API只能拿到用户的加密数据,如:微信步数。

官方文档对此已提供了较为详细的解决方案,本文用 JavaScript 写请求与 NodeJS 写接口部署实践,希望让前端视角的小伙伴更能一目了然整体流程。

如果你是Java,官方文档也提供了各种语言的解密算法:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#方式一:开发者后台校验与解密开放数据

 

02 流程:

1. 前端调用 wx.login 登录拿到 code

2. 前端调用 code2Session 接口获取 openid,session_key。

此处后端通过小程序运营后台的 appid,secret 及前端传来的 code 调用微信 sdk 获取 openid,session_key并返回

app.post('/code2Session', (req, res)=>{
    const result = {data: {}};
    if(!req.body?.code) {
        result.msg = `缺少登录获取的code参数`;
        result.code = '0';
        return res.json(result);
    }
    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${req.body.code}&grant_type=authorization_code`;
    const options = {
        headers: {}
    };
    https.get(url, options, httpsres => {
        httpsres.setEncoding('utf8');
        // 监听返回的数据
        httpsres.on('data', (data) => {
            result.msg = `success`;
            result.code = '200';
            result.data = data;
        });
        // 监听接口请求完成, 除非error,最终都会执行end;
        httpsres.on('end', () => {
            return res.json(result);
        });
    }).on('error', err => {
        result.msg = `getToken失败————${err}`;
        result.code = '0';
        return res.json(result);
    });
})


3. 前端拿到openid,session_key存储供后续使用

4. 前端调用解密接口获取解密数据

此处后端通过前端传递的 sessionKey,encryptedData,iv 调用官方提供的解密算法并返回数据

注:前端调用敏感数据API时,会拿到加密数据 encryptedData,加密算法的初始向量 iv

app.post('/decode', (req, res)=>{
    const result = {data: {}};
    const { sessionKey='', encryptedData='', iv='' } = req.body;
    if(!(sessionKey && encryptedData && iv)) {
        result.msg = `必要参数sessionKey, encryptedData, iv`;
        result.code = '0';
        return res.json(result);
    }
    const pc = new WXBizDataCrypt(appid, sessionKey);
    result.msg = `success`;
    result.code = '200';
    result.data = pc.decryptData(encryptedData , iv);
    return res.json(result);
})


示例:node解密算法如下

function WXBizDataCrypt(appid, sessionKey) {
  this.appid = appid
  this.sessionKey = sessionKey
}
WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // base64 decode
  var sessionKey = new Buffer(this.sessionKey, 'base64')
  encryptedData = new Buffer(encryptedData, 'base64')
  iv = new Buffer(iv, 'base64')
  try {
     // 解密
    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
    // 设置自动 padding 为 true,删除填充补位
    decipher.setAutoPadding(true)
    var decoded = decipher.update(encryptedData, 'binary', 'utf8')
    decoded += decipher.final('utf8')
    decoded = JSON.parse(decoded)
  } catch (err) {
    throw new Error('Illegal Buffer1')
  }
  if (decoded.watermark.appid !== this.appid) {
    throw new Error('Illegal Buffer2')
  }
  return decoded
}


最后一次编辑于  2022-05-17  
点赞 2
收藏
评论
登录 后发表内容