解密微信小程序API返回的加密数据

Wed 10 January 2018 / In categories Development

WeChat, nodejs

微信小程序API返回的部分数据是经过加密啊的,需要对其进行解密才能获得原始内容。根据用户数据的签名验证和加解密介绍的解密方法,本文采用aes-jsbase64-js对加密数据进行解密。

首先用yarn(或者npm)安装aes-jsbase64-js

yarn init #初始化package.json
yarn add base64-js
yarn add aes-js

编写代码片段进行测试

var aesjs = require('aes-js')
var base64js = require('base64-js')

var sessionKey = 'tiihtNczf5v6AKRyjwEUhQ=='
var iv = 'r7BXXKkLb8qrSNn05n0qiA=='

var encryptedData = 
	'CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM'+
	'QmRzooG2xrDcvSnxIMXFufNstNGTyaGS'+
	'9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+'+
	'3hVbJSRgv+4lGOETKUQz6OYStslQ142d'+
	'NCuabNPGBzlooOmB231qMM85d2/fV6Ch'+
	'evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6'+
	'/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw'+
	'u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn'+
	'/Hz7saL8xz+W//FRAUid1OksQaQx4CMs'+
	'8LOddcQhULW4ucetDf96JcR3g0gfRK4P'+
	'C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB'+
	'6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns'+
	'/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd'+
	'lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV'+
	'oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG'+
	'20f0a04COwfneQAGGwd5oa+T8yO5hzuy'+
	'Db/XcxxmK01EpqOyuxINew=='


function getDecryptedText(key, iv, data) {
  var aesCbc = new aesjs.ModeOfOperation.cbc(
    base64js.toByteArray(key),
    base64js.toByteArray(iv)
  )
  var decryptedBytes = aesCbc.decrypt(
    base64js.toByteArray(data)
  )
  var stripped = aesjs.padding.pkcs7.strip(decryptedBytes)
  return aesjs.utils.utf8.fromBytes(stripped)
}

console.log(getDecryptedText(sessionKey, iv, encryptedData))

上述代码保存为index.js,运行node index.js得到解密的数据:

{"openId":"oGZUI0egBJY1zhBYw2KhdUfwVJJE","nickName":"Band","gender":1,"language":"zh_CN","city":"Guangzhou","province":"Guangdong","country":"CN","avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0","unionId":"ocMvos6NjeKLIBqg5Mr9QjxrP1FA","watermark":{"timestamp":1477314187,"appid":"wx4f4bc4dec97d474b"}}

整合到小程序项目中

需要做几个操作

  • node_modules/js-base64/base64.min.js拷到小程序项目根目录下的*/utils*目录
  • node_modules/aes-js/index.js拷到小程序项目根目录下的*/utils*目录,并重命名成aesjs.js(可以使用uglifyjsaesjs.js进行压缩,体积有稍许减少)

创建一个crypt.js文件,内容如下:

const aesjs = require('./asejs.js')
const base64js = require('./base64js.min.js')

function getDecryptedText(key, iv, data) {
  var aesCbc = new aesjs.ModeOfOperation.cbc(
    base64js.toByteArray(key),
    base64js.toByteArray(iv)
  )
  var decryptedBytes = aesCbc.decrypt(
    base64js.toByteArray(data)
  )
  var stripped = aesjs.padding.pkcs7.strip(decryptedBytes)
  return aesjs.utils.utf8.fromBytes(stripped)
}

module.exports = {
  getDecryptedText: getDecryptedText
}

这样,在小程序页面的js文件中可以使用以下方式来解密数据:

const crypt = require("../../utils/crypt.js")
crypt.getDecryptedText(key, res.iv, res.encryptedData)

getDecryptedText的输入是经过base64编码的session key、iv和加密过的数据,集体参考[用户数据的签名验证和加解密

总结

这篇文章里面的方案只使用到了aes-jsbase64-js,包含进来的文件体积算比较小的,但是功能也比较单一。

网上还有其他方案,比如

(完)

Load Disqus Comments