微信小程序解密
- 格式:pptx
- 大小:2.58 MB
- 文档页数:50
微信⼩程序⼿机号解密失败-43001
今天是2020年1⽉16号,从昨天下午开始,⼀直遇到⼀个问题:客户在注册会员的时候的第⼆步,验证⼿机号的时候,⼀直提⽰验证失败,-43001
直接说原因:⽤户的session_key过期
期间⼤部分⽤户都是直接可以获取到的,只有很少⼏个⽤户点了允许按钮,⼀直没有反应,后台将错误信息保存了起来显⽰的结果是-43001,也就是解密失败。
极少数的是-42001是因为获取验证码太多次了,腾讯那边就没有返回了,这个要等⼀会⼉就可以了。
最后发现,原因是:失败的那些⽤户,⼀直都是⼩程序的⽼⽤户,他们原先很早就使⽤过⼩程序了,但是后来⼀直没使⽤过,导致数据库⾥的session_key过期了,所以才会获取不到⼿机号。
bug很简单却不容易解决,希望能帮到遇到这个问题的同学。
微信⼩程序java登录授权解密获取unionId(填坑)官⽅流程图:第⼀步:获取code说明:⼩程序调⽤wx.login() 获取临时登录凭证code ,并回传到开发者服务器。
开发者服务器以code换取⽤户唯⼀标识openid 和会话密钥session_key。
之后开发者服务器可以根据⽤户标识来⽣成⾃定义登录态,⽤于后续业务逻辑中前后端交互时识别⽤户⾝份。
//app.jsApp({onLaunch: function() {wx.login({success: function(res) {if (res.code) {//发起⽹络请求wx.request({url: 'https:///onLogin',data: {code: res.code}})} else {console.log('登录失败!' + res.errMsg)}}});}})关于unionId,这⾥需要说明⼀下,如果应⽤只限于⼩程序内则不需要unionId,直接通过openId可以确定⽤户⾝份,但是如果需要跨应⽤如:⽹页应⽤,app应⽤时则需要使⽤到unionId作为⾝份标识。
UnionID获取途径绑定了开发者帐号的⼩程序,可以通过下⾯3种途径获取UnionID。
调⽤接⼝wx.getUserInfo,从解密数据中获取UnionID。
注意本接⼝需要⽤户授权,请开发者妥善处理⽤户拒绝授权后的情况。
如果开发者帐号下存在同主体的公众号,并且该⽤户已经关注了该公众号。
开发者可以直接通过wx.login获取到该⽤户UnionID,⽆须⽤户再次授权。
如果开发者帐号下存在同主体的公众号或移动应⽤,并且该⽤户已经授权登录过该公众号或移动应⽤。
开发者也可以直接通过wx.login获取到该⽤户UnionID,⽆须⽤户再次授权。
说明完了,我们继续下⼀步,主要需要区分获得授权,和未获得授权情况第⼆步:通过code换取sessionKey等个⼈信息1、未获得授权注意:这⾥unionId如果满⾜上⾯2、3所说获取条件,则会在这⼀步⾥返回,如果不满⾜则需要调⽤wx.getUserInfo来获取,这个⽅法需要获得⽤户授权。
微信⼩程序授权登录及解密unionId出错的⽅法注:没有在微信开放平台做开发者资质认证的就不要浪费时间了,没认证⽆法获取unionId,认证费⽤300元/年,emmmm....微信授权登录流程第⼀步:wx.login获取⽤户临时登录凭证code第⼆步:wx.getUserInfo获取加密过的数据encryptedData和解密参数iv第三步:把步骤⼀、⼆中的code、encryptedData、iv传到开发者⾃⼰服务端第三步:服务端获取到code、encryptedData、iv之后⽤get⽅法请求如下微信接⼝appid:⼩程序appidsecret:⼩程序密钥js_code:第⼀步获取的临时登录凭证codegrant_type:'authorization_code'接⼝会返回 openid, session_key,注意:⽤户已经授权过的平台还会返回unionId,如果你只是需要unionId,则到此为⽌官⽅⽂档说法如图:没有授权过则⽤encryptedData、session_key、iv、appid、secret进⾏解密,官⽅多语⾔解密⽰例下载链接:包含c++ php python node第四步:仿照⽰例解密后获得unionId,想做什么就做什么了~以下是授权登录前端代码:authLogin () {wx.login({success: loginRes => {let code = loginRes.code // 获取⽤户临时codewx.getUserInfo({success: function (res) {let encryptedData = res.encryptedData // 获取加密数据let iv = res.iv // 解密参数// 发送解密必要数据到服务端wx.request({url: 'http://localhost',methods: 'POST',data: {code: code,encryptedData: encryptedData,iv: iv},succeess: res => {// 服务端⾸先调⽤微信接⼝获取session_key// ⽤户已经授权过的平台会直接返回unionId// 没有授权过则⽤session_key进⾏解密// 解密成功后服务端根据逻辑返回⾃定义信息}})}})}})}以上步骤可⾏,但是微信调整了⽤户授权⽅式新的授权需⽤button组件调⽤getUserInfo,所以在这之前⽆法调⽤wx.login,但是如果先调⽤获取⽤户信息再调⽤wx.login的话,解密过程会出错,猜测code对应的session_key和之前getUserInfo获取的encryptedData不匹配解决办法:在页⾯的onLoad⽣命周期⾥调⽤wx.login,获取的code存⼊data以备需要的时候使⽤,但是code失效时间为5分钟,如果⽤户停留页⾯时间过长后点击授权登录,此时的code已经过期了,所以,获取code的函数应该每4分钟左右调⽤⼀次wxml按钮授权:<button open-type='getUserInfo' bindgetuserinfo="authLogin">微信登录</button>js:// 获取codeonLoad: function (options) {this.getCodeTimer()},getCodeTimer () {wx.login({success: res => {this.data.code = res.codesetTimeout(() => {this.getCodeTimer()}, 4 * 60 * 1000)}})},// 授权登录authLogin(event) {if (event.detail.errMsg == 'getUserInfo:ok') {wx.showLoading()let reqData = {code: this.data.code,encryptedData: event.detail.encryptedData,iv: event.detail.iv}wx.request({url: 'http://localhost:8080',methods: 'POST',data: reqData,success: (res) => {console.log(res)// 请求完成}})} else {console.log('⽤户拒绝授权')}}授权逻辑修改后实测没有出过错以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
5分钟学会PC端⼩程序解包(详细教学步骤)
简介
通过⼩程序解包后在源码中可以找到更多有⽤信息,懂得都懂。
正⽂
1、下载软件
⾸先下载相关⼯具,有些⼯具需要⾃⼰⼿动配置环境。
这⾥我⽤的是吾爱破解上⼤佬写的⼯具,环境⾃动配置好,⽅便简单好⽤。
如果下载链接失效,可以去作者的地址查看最新下载地址。
2、⼩程序解包
微信⼩程序搜索我们要解包的⼩程序,点击进去。
让电脑进⾏加载⼩程序,缓存⼩程序⽂件到本地。
然后微信设置查看⽂件管理,微信⽂件保存的位置。
⼩程序包也储存在那⾥,可以看到wx开头就是。
可以看到电脑已经缓存了刚才的⼩程序⽂件,默认的路径⼀般在C:\Users\Administrator\Documents\WeChat Files\Applet位置。
找不到的话可以搜索applet,查看路径。
wx开头的都是。
找到⾃⼰要解包的⼩程序,如果太多分不清哪个是我们需要的话,可以把wx开头的⽂件清空删除,重新加载⼩程序,⽣成新的。
就是我们能需要的。
点击到⽂件⾥⾯,会看到_APP_开头的主包,打开下载好的⼩程序,选择PC⼩程序解包,把⾥⾯的_APP_.wxapkg拖拽进去,选择解包后保存的路径,点击开始解密。
然后选择⼩程序反编译,把解包出来的⽂件放进去,选择保存的路径。
点击开始反编译。
找到反编译后保存的路径,⼤功告成。
这么简单,学废了吗?。
微信⼩程序开发之获取⽤户⼿机号码——使⽤简单php接⼝demo进⾏加密数据解密后边要做⼀个微信⼩程序,并要能获取⽤户微信绑定的⼿机号码。
⽽⼩程序开发⽂档上边提供的获取⼿机号码的接⼝(getPhoneNumber())返回的是密⽂,需要服务器端进⾏解密,但是官⽅提供的开发⽂档⼀如既往的乱,如果没有对⼩程序开发⽂档有⼀个整体的了解,搞懂解密流程还是有点难的。
这⾥把⼩程序从请求⽤户授权获取⼿机号码直⾄获取到⼿机号码明⽂的整个流程串了起来,⽅便迅速了解,如下:⼀. 前端相关操作:1. 请求⽤户授权获取⼿机号码:因为需要⽤户主动触发才能发起获取⼿机号接⼝,所以该功能不由 API 来调⽤,需⽤<button>组件的点击来触发,如下:wxml:<button wx:if="{{!phone}}" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取⼿机号码</button>js:1 Page({2 getPhoneNumber: function(e) { 3if(e.detail.errMsg == "getPhoneNumber:fail user deny") return; //⽤户允许授权 4 console.log("lv", e.detail.iv); //包括敏感数据在内的完整⽤户信息的加密数据,需要解密 5 console.log(e.detail.encryptedData); //加密算法的初始向量,解密需要⽤到 6 ......7 }8 })2. 访问⼩程序登录接⼝:⼩程序调⽤wx.login()获取临时登录凭证code,并传到开发者服务器。
Page({getPhoneNumber: function(e) {console.log(e.detail.errMsg)console.log(e.detail.iv) //包括敏感数据在内的完整⽤户信息的加密数据,需要解密console.log(e.detail.encryptedData) //加密算法的初始向量,解密需要⽤到wx.login({success: res => {if(res.code){console.log(res.code)}}})}})3. 访问腾讯服务器的登录凭证校验接⼝:注:官⽅推荐放到服务器端进⾏,这⾥为了⽅便,就放在前端请求了。
PC微信⼩程序解密和反编译资源https:///BlackTrace/pc_wxapkg_decrypt由于不想安装安卓模拟器去提取wxapkg包,windows PC端的微信也⽀持⼩程序,但是PC端的wxapkg是被加密存储的。
该项⽬是把wxapkg解密。
⽬前微信PC版本为:2.9.5.31.使⽤⽅法pc_wxapkg_decrypt.exe -wxid 微信⼩程序id -in 要解密的wxapkg路径 -out 解密后的路径pc_wxapkg_decrypt.exe -hUsage of pc_wxapkg_decrypt.exe:-in string需要解密的wxapkg的⽂件路径 (default "__APP__.wxapkg")-iv stringAES加密的IV,默认不需要设置,如果版本有变化,设置 (default "the iv: 16 bytes")-out string解密后的wxapkg的⽂件路径 (default "dec.wxapkg")-salt stringpbkdf2⽤到的salt,默认不需要设置 (default "saltiest")-wxid string⼩程序的idwxapkg路径为:C:\Users\xxxx\Documents\WeChat Files\Applet\wx2xxx84w9w7a3xxxx\_APP_.wxapkg,⼩程序id为:wx2xxx84w9w7a3xxxx解密完成后,就可以⽤wxappUnpacker(原理PC端微信把wxapkg给加密,加密后的⽂件的起始为V1MMWX。
加密⽅法为:1. ⾸先pbkdf2⽣成AES的key。
利⽤微信⼩程序id字符串为pass,salt为saltiest 迭代次数为1000。
调⽤pbkdf2⽣成⼀个32位的key2. ⾸先取原始的wxapkg的包得前1023个字节通过AES通过1⽣成的key和iv(the iv: 16 bytes),进⾏加密3. 接着利⽤微信⼩程序id字符串的倒数第2个字符为xor key,依次异或1023字节后的所有数据,如果微信⼩程序id⼩于2位,则xorkey为 0x664. 把AES加密后的数据(1024字节)和xor后的数据⼀起写⼊⽂件,并在⽂件头部添加V1MMWX标识。
微信⼩程序获取⼿机号JavaScript解密⽰例代码详解当我们在开发微信⼩程序中,有⼀个常⽤的功能,就是获取⽤户的⼿机号,然后⼀键登⼊⼩程序,那么⼿机号如何获取呢?请认真看完本⽂,保证可以获取到⽤户的⼿机号。
刚开始开发微信⼩程序的时候,想着实现⼿机验证码登⼊,后来查阅资料得知,发给⽤户的短信是要⾃⼰付费的。
后来想想,微信获取⽤户的⼿机号⼀样可以保证⼿机号码的真实性,因为⼿机号既然可以绑定微信,那么肯定是被严格核验过的,然后就开始了获取⼿机号之旅,⽹上教程有很多,但不知什么原因,都是会少⼀些内容,有的只有前端代码,没有后端;有的后端代码是PHP,不是我们想要的 Java 或者JavaScript。
我抱着开源的思想,给⼤家分享我获取⼿机号的办法,希望能帮到⼤家。
⾸先我们可以去看⼀看官⽅⽂档,获取⼿机号⼤致分为以下四步:第1步:使⽤wx.login接⼝获取code(临时数据)第2步:使⽤第⼀步的code,获取session_key和openid(确认⽤户唯⼀的数据)第3步:使⽤getPhoneNumber接⼝,获取iv和encryptedData(获取加密的数据)第4步:解密返回数据,获取⼿机号码(解密后的数据)下⾯详细讲解:第⼀步:使⽤wx.login接⼝获取code(临时数据)官⽅⽂档是这么写的:获取微信⽤户绑定的⼿机号,需先调⽤wx.login接⼝。
因为需要⽤户主动触发才能发起获取⼿机号接⼝,所以该功能不由 API 来调⽤,需⽤ button 组件的点击来触发。
注意:⽬前该接⼝针对⾮个⼈开发者,且完成了认证的⼩程序开放(不包含海外主体)。
需谨慎使⽤,若⽤户举报较多或被发现在不必要场景下使⽤,微信有权永久回收该⼩程序的该接⼝权限。
我们可以提炼出下⾯⼏条关键信息:只能由⾮个⼈的⼩程序才能获取⽤户⼿机号。
获取⼿机号必须由button按钮组件触发,⽽不能写在onLoad()内⾃动获取。
需在必要的情况下使⽤。
微信⼩程序登录状态java后台解密⼀、登录流程图⼆、微信⼩程序端doLogin:function(callback = () =>{}){let that = this;wx.login({success:function(loginRes){if(loginRes){//获取⽤户信息wx.getUserInfo({withCredentials:true,//⾮必填默认为truesuccess:function(infoRes){console.log(infoRes,'>>>');//请求服务端的登录接⼝wx.request({url: api.loginUrl,data:{code:loginRes.code,//临时登录凭证rawData:infoRes.rawData,//⽤户⾮敏感信息signature:infoRes.signature,//签名encrypteData:infoRes.encryptedData,//⽤户敏感信息iv:infoRes.iv//解密算法的向量},success:function(res){console.log('login success');res = res.data;if(res.result==0){erInfo = erInfo;wx.setStorageSync('userInfo',JSON.stringify(erInfo));wx.setStorageSync('loginFlag',res.skey);console.log("skey="+res.skey);callback();}else{that.showInfo('res.errmsg');}},fail:function(error){//调⽤服务端登录接⼝失败// that.showInfo('调⽤接⼝失败');console.log(error);}});}});}else{}}});}微信⼩程序端发起登录请求,携带的参数主要有:code:loginRes.code,//临时登录凭证rawData:infoRes.rawData,//⽤户⾮敏感信息signature:infoRes.signature,//签名encrypteData:infoRes.encryptedData,//⽤户敏感信息iv:infoRes.iv//解密算法的向量需要的数据主要有:result、userInfo和skeyresult⽤来判断是否登录成功,userInfo是⽤户的⼀些信息,保存在缓存中,不⽤每次都从后台获取,skey是⽤户登录态标识,也放在缓存中,如果skey存在就直接登录,维护⽤户的登录状态,具有时效性三、Java后台@ResponseBody@RequestMapping("/login")public Map<String,Object> doLogin(Model model,@RequestParam(value = "code",required = false) String code,@RequestParam(value = "rawData",required = false) String rawData,@RequestParam(value = "signature",required = false) String signature,@RequestParam(value = "encrypteData",required = false) String encrypteData, @RequestParam(value = "iv",required = false) String iv){( "Start get SessionKey" );Map<String,Object> map = new HashMap<String, Object>( );System.out.println("⽤户⾮敏感信息"+rawData);JSONObject rawDataJson = JSON.parseObject( rawData );System.out.println("签名"+signature);JSONObject SessionKeyOpenId = getSessionKeyOrOpenId( code );System.out.println("post请求获取的SessionAndopenId="+SessionKeyOpenId);String openid = SessionKeyOpenId.getString("openid" );String sessionKey = SessionKeyOpenId.getString( "session_key" );System.out.println("openid="+openid+",session_key="+sessionKey);User user = userService.findByOpenid( openid );//uuid⽣成唯⼀keyString skey = UUID.randomUUID().toString();if(user==null){//⼊库String nickName = rawDataJson.getString( "nickName" );String avatarUrl = rawDataJson.getString( "avatarUrl" );String gender = rawDataJson.getString( "gender" );String city = rawDataJson.getString( "city" );String country = rawDataJson.getString( "country" );String province = rawDataJson.getString( "province" );user = new User();user.setUid( openid );user.setCreateTime( new Date( ) );user.setSessionkey( sessionKey );user.setUbalance( 0 );user.setSkey( skey );user.setUaddress( country+" "+province+" "+city );user.setUavatar( avatarUrl );user.setUgender( Integer.parseInt( gender ) );user.setUname( nickName );user.setUpdateTime( new Date( ) );userService.insert( user );}else {//已存在( "⽤户openid已存在,不需要插⼊" );}//根据openid查询skey是否存在String skey_redis = (String) redisTemplate.opsForValue().get( openid );if(StringUtils.isNotBlank( skey_redis )){//存在删除 skey 重新⽣成skey 将skey返回redisTemplate.delete( skey_redis );}// 缓存⼀份新的JSONObject sessionObj = new JSONObject( );sessionObj.put( "openId",openid );sessionObj.put( "sessionKey",sessionKey );redisTemplate.opsForValue().set( skey,sessionObj.toJSONString() );redisTemplate.opsForValue().set( openid,skey );//把新的sessionKey和oppenid返回给⼩程序map.put( "skey",skey );map.put( "result","0" );JSONObject userInfo = getUserInfo( encrypteData, sessionKey, iv );System.out.println("根据解密算法获取的userInfo="+userInfo);userInfo.put( "balance",user.getUbalance() );map.put( "userInfo",userInfo );return map;}获取openid和sessionKey⽅法public static JSONObject getSessionKeyOrOpenId(String code){//微信端登录codeString wxCode = code;String requestUrl = "https:///sns/jscode2session";Map<String,String> requestUrlParam = new HashMap<String, String>( );requestUrlParam.put( "appid","你的⼩程序appId" );//⼩程序appIdrequestUrlParam.put( "secret","你的⼩程序appSecret" );requestUrlParam.put( "js_code",wxCode );//⼩程序端返回的coderequestUrlParam.put( "grant_type","authorization_code" );//默认参数//发送post请求读取调⽤微信接⼝获取openid⽤户唯⼀标识JSONObject jsonObject = JSON.parseObject( UrlUtil.sendPost( requestUrl,requestUrlParam )); return jsonObject;}解密⽤户敏感数据获取⽤户信息public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){// 被加密的数据byte[] dataByte = Base64.decode(encryptedData);// 加密秘钥byte[] keyByte = Base64.decode(sessionKey);// 偏移量byte[] ivByte = Base64.decode(iv);try {// 如果密钥不⾜16位,那么就补⾜. 这个if 中的内容很重要int base = 16;if (keyByte.length % base != 0) {int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);byte[] temp = new byte[groups * base];Arrays.fill(temp, (byte) 0);System.arraycopy(keyByte, 0, temp, 0, keyByte.length);keyByte = temp;}// 初始化Security.addProvider(new BouncyCastleProvider());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");parameters.init(new IvParameterSpec(ivByte));cipher.init( Cipher.DECRYPT_MODE, spec, parameters);// 初始化byte[] resultByte = cipher.doFinal(dataByte);if (null != resultByte && resultByte.length > 0) {String result = new String(resultByte, "UTF-8");return JSON.parseObject(result);}} catch (NoSuchAlgorithmException e) {log.error(e.getMessage(), e);} catch (NoSuchPaddingException e) {log.error(e.getMessage(), e);} catch (InvalidParameterSpecException e) {log.error(e.getMessage(), e);} catch (IllegalBlockSizeException e) {log.error(e.getMessage(), e);} catch (BadPaddingException e) {log.error(e.getMessage(), e);} catch (UnsupportedEncodingException e) {log.error(e.getMessage(), e);} catch (InvalidKeyException e) {log.error(e.getMessage(), e);} catch (InvalidAlgorithmParameterException e) {log.error(e.getMessage(), e);} catch (NoSuchProviderException e) {log.error(e.getMessage(), e);}return null;}四、流程1.⼩程序端发起请求并携带主要参数2.java后台接到/login请求后,根据code去调⽤微信接⼝获取⽤户唯⼀标识openid和sessionKey3.根据openid查询mysql数据库,判断该⽤户是否存在,如果不存在将⽤户⾮敏感信息和其他初始化数据存⼊到数据库中,如果已存在,不操作4.根据openid查询redis数据库,判断openid对应的skey是否存在,如果存在则删除原来⽼的skey以及对应的openid和sessionKey5.通过uuid⽣成唯⼀的skey,⽤openid做键,skey做值,存⼊到redis中6.然后把skey做键,openid和sessionKey的json串做值也重新存⼊到redis中7.根据解密算法,参数有encryptedData、sessionKey和iv,获取⽤户信息userInfo,如果userInfo字段不满⾜需要,可通过userInfo.put( “balance”,user.getUbalance() );添加所需要的字段和值8.将微信⼩程序需要的数据封装到map中,返回给⼩程序端map.put( "skey",skey );map.put( "result","0" );map.put( "userInfo",userInfo );return map;以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
一、备份微信数据找一台刚玩过要反编译微信小游戏的小米手机(因为没办法通过文件名看出是不是要自己要的小游戏),然后设置——更多设置——设置和重置——本地备份——新建备份——软件程序——只选中微信,开始备份。
二、MIUI备份bak文件还原出明文数据1、将目标Bak备份数据拷贝到电脑端小米MIUI手机备份后的文件会存放在手机存储下/MIUI/backup/Allbackup/xxx 目录中(xxx 代表备份的时间)。
童鞋们需要做的就是将需要解包的目标Bak文件复制到你的电脑上。
怎么复制?QQ传文件、连接数据线等等都可以,这里就不罗嗦了。
2、借用WinHex简单修改一下Bak文件头(图1)打开WinHex 神器,直接将你拷贝好的Bak文件拖拽进去,这里就会发现其实MIUI备份只是多出了一个自定义文件头而已,那就简单啦,只要移除这个文件头就好!操作时,只要按图示的方法选中并删除“41 4E”前面的数据即可,完成后记得保存!3、将修改后的Bak直接使用”解包小米Bak.bat”来正常解包就搞定了(图2,3)解包后的文件格式为tar,可以通过解压缩软件打开查看。
三、微信小程序(.wxapkg)文件解包在解包后的小米备份文件夹中找到.wxapkg所在文件夹,按日期排列。
日期最近的那个就是你刚玩过的。
如下图进行解包,解包后会生成一个同名的文件夹,这就是解包后的小游戏源码了。
四、还原项目将解包出来的文件夹中的所有文件复制到template文件夹中,如有同名的请跳过。
编译源码通过微信小游戏开发工具新建一个空白的小程序或者小游戏的项目,主要不要选择快速启动模板然后把刚才解压出来的源代码复制到刚刚创建的项目目录中,开发工具会提示编译错误,这时只要在项目中新建一个game.json 文件,并在文件里写入以下代码{"deviceOrientation" : "portrait"}复制代码然后将开发工具的调试基础库改为game程序就会在开发者工具里运行起来了(图4、5)。
微信⼩程序encryptedData的解密(JAVA)上图为微信官⽅api提供的登陆获取⽤户信息的流程,session_key的得到这⾥不进⾏说明,详情可以看微信⼩程序的官⽅api。
数据签名校验为了确保开放接⼝返回⽤户数据的安全性,微信会对明⽂数据进⾏签名。
开发者可以根据业务需要对数据包进⾏签名校验,确保数据的完整性。
通过调⽤接⼝(如 wx.getUserInfo)获取数据时,接⼝会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )开发者将 signature、rawData 发送到开发者服务器进⾏校验。
服务器利⽤⽤户对应的 session_key 使⽤相同的算法计算出签名 signature2 ,⽐对 signature 与 signature2 即可校验数据的完整性。
以上描述即为微信⼩程序传过来的 rawData 和已经得到session_key进⾏sha1加密之后的值如果和signature相等的话就表明数据校验通过,加密数据解密算法接⼝如果涉及敏感数据(如wx.getUserInfo当中的 openId 和unionId ),接⼝的明⽂内容将不包含这些敏感数据。
开发者如需要获取敏感数据,需要对接⼝返回的加密数据( encryptedData )进⾏对称解密。
解密算法如下:对称解密使⽤的算法为 AES-128-CBC,数据采⽤PKCS#7填充。
对称解密的⽬标密⽂为 Base64_Decode(encryptedData)。
对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
对称解密算法初始向量为Base64_Decode(iv),其中iv由数据接⼝返回。
微信官⽅提供了多种编程语⾔的⽰例代码(点击下载)。
每种语⾔类型的接⼝名字均⼀致。
调⽤⽅式可以参照⽰例。