前要: 今天调试一下微信授权登录的时候老是第一次报错解密失败pad block corrupted,第二次授权的时候正常,因为第一次已经获取到手机号码!

后端代码:

public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {try {// 加密秘钥byte[] keyByte = Base64.decodeBase64(sessionKey);// 偏移量byte[] ivByte = Base64.decodeBase64(iv);// 如果密钥不足16位,那么就补足.  这个if 中的内容很重要int base = 16;if (keyByte.length % base != 0) {int groups = keyByte.length / base + 1;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[] dataByte = Base64.decodeBase64(encryptedData);byte[] resultByte = cipher.doFinal(dataByte);if (null != resultByte && resultByte.length > 0) {String result = new String(resultByte, StandardCharsets.UTF_8);log.info("解析微信加密数据==>{}", result);return JSONObject.parseObject(result);}} catch (BadPaddingException e) {log.error("解析微信加密数据失败", e);throw Exceptions.fail(WECHAT_SESSION_EXPIRED);}return null;}

报错提示:

javax.crypto.BadPaddingException: pad block corruptedat org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(Unknown Source)at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)at javax.crypto.Cipher.doFinal(Cipher.java:2088)at com.saic.ebiz.service.util.AESUtils.getUserInfo(AESUtils.java:62)at com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:96)
Exception in thread "main" java.lang.NullPointerExceptionat com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:96)

查找了官方文档原来不是后端代码问题,而是前端代码问题~是微信的bug。不知道有没有解决,但我们自己可以去解决:就是执行顺序问题

原因: uni.login获取session_key,而sessionKey又是解密encryptedData的密钥,所以一旦我们的uni.login在uni.getUserInfo(getPhoneNumber)之后获取,我们存储的sessionKey绝对不是当前获取encryptedData的密钥。

  • 这是因为调用了uni.login后通过code获得的session_key是新的session_key.
  • 所以,在调用uni.login之前获的加密数据不是用新得session_key加密的数据。
  • 在调用uni.login之后获得的加密数据,才是新得的session_key加密的数据。

本来的执行顺序:

  1. 先触发getPhoneNumber获取了手机号的加密数据。
  2. 然后才调用的uni.login获取code。
  3. 再通过code取到用户的session_key 。
  4. 最后再用session_key,手机号的加密数据和向量解密获取手机号。

正确的做法应该是:

  1. 首先调用的uni.login获取code
  2. 再通过code取到用户session_key 。
  3. 再触发getPhoneNumber获取了手机号的加密数据
  4. 最后再用session_key,手机号的加密数据和向量解密获取手机号。

前端保证uni.login获取到的code在getUserInfo(getPhoneNumbe)操作之前。也可以是后端,因为项目是graphql,所以我是前端保证就行。社区还提供另外一种方案Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS7Padding”, “BC”);中BC去掉,不知道行不行!可以试一下!!!

setTab(index) {let that = this;that.tabIndex = index;if (index == 1) {uni.login({provider: 'weixin',success: function(loginRes) {that.loginResCode = loginRes.code;}})}
},
getPhoneNumber: function(e) {console.log('aaaaaaaa', e)if (e.detail.errMsg != "getPhoneNumber:ok") {return console.log('用户拒绝请求')}let self = this;let fromData = {rawData: e.detail.encryptedData,iv: e.detail.iv,code: self.loginResCode}self.$api.wxLogin(fromData).then(res => {if (res.data.code == 200) {self.$store.commit('changeUserInfo', res.data.data);self.$store.commit('changeLoginStatus', true);self.$store.commit('changeToken', res.header.accesstoken || res.header.accessToken);// uni.navigateBack();var pages = getCurrentPages(); // 当前页面var beforePage = pages[pages.length - 2]; // 前一个页面if (beforePage) {uni.navigateBack()} else {uni.switchTab({url: '/pages/home/home'})}} else {uni.showModal({title: '提示',content: res.data.msg,showCancel: false,success: function(res) {if (res.confirm) {console.log('用户点击确定');} else if (res.cancel) {console.log('用户点击取消');}}});}})
},

微信小程序解密encryptedData报错pad block corrupted相关推荐

  1. 微信小程序解密encryptedData报错:pad block corrupted 解决方法

    今天碰到一个pad block corrupted错误,跟代码发现是Cipher里面的doFinal()爆出的错. 代码: public static JSONObject getUserInfo(S ...

  2. 微信小程序授权信息报错:pad block corrupted

    接手的老代码中,授权用户信息和授权手机号之前每次都会调用wx.login 导致新用户第一次授权用户信息一定报错 之后后端打印日志发现报错pad block corrupted,经过看网上的解决办法后发 ...

  3. 微信小程序渲染图片报错:[渲染层网络层错误] Failed to load local image resource

    微信小程序渲染图片报错解决:[渲染层网络层错误] Failed to load local image resource 背景 通过用户点击上传图片,通过res.tempFilePaths拿到用户上传 ...

  4. 微信小程序request:fail报错(包括不执行fail回调问题)

    微信小程序request:fail报错(包括不执行fail回调的问题) 1. 不执行fail回调的问题 2. request:fail报错原因 2.1 小程序未配置域名导致的错误 2.2 微信小程序使 ...

  5. uniapp引入自定义组件canvas 不现实,运行到微信小程序端时会报错

    问题1 在引入自定义canvas组件时,在微信开发者工具中为空白,和h5中不现实 原因 在微信开发者工具 错误案例,没有加实例化this 在h5中不实现为空白是没有onReady里面实例化canvas ...

  6. 微信小程序授权登录报错encryted_data或iv不合法,前端坑^-^~~

    微信小程序授权登录原来用的wx.getUserInfo(),在用户未授权过的情况下调用此接口,将不再出现授权弹窗, 会直接进入 fail 回调(详见<公告>).在用户已授权的情况下调用此接 ...

  7. 微信小程序 常见问题(报错)

    微信小程序 常见问题: 微信小程序项目结构 主要有四个文件类型,如下 WXML (WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. ...

  8. 微信小程序滴滴服务器报错,如何使用mpx框架(滴滴)给微信小程序分包

    如何使用mpx框架(滴滴)给微信小程序分包 如何使用mpx框架(滴滴)给微信小程序分包 前提:使用mpx框架.核心包:@mpxjs/core.@mpxjs/webpack-plugin等 mpx开发文 ...

  9. 微信小程序中定位报错在app.json中声明permission字段

    微信小程序在获取用户位置时后台报错 在搭建小程序的过程中出现报错,报错内容:getLocation需要在app.json中声明permission字段. 出现这类的提示,获取不到用户的地理位置,其实提 ...

最新文章

  1. 技术图文:如何利用BigOne的API制作自动化交易系统 -- 获取账户资产
  2. python是一门什么课程-从无到有用Python创造一门属于自己的编程语言1
  3. Android应用程序目录结构框架搭建
  4. IEEE的论文需要注意的一些
  5. 如何保证access_token长期有效
  6. 更改IE浏览器默认的源文件编辑器
  7. Android mock for循环,Android单元测试(五):依赖注入,将mock方便的用起来
  8. 潭州课堂25班:Ph201805201 爬虫高级 第三课 sclapy 框架 腾讯 招聘案例 (课堂笔记)...
  9. 编辑距离Edit distance
  10. Spring Boot最核心的21个注解
  11. C++ std::set insert 失败 原因和解决方案 operator
  12. [软件工程] 数据字典
  13. 【ceph】vdbench的使用教程——裸盘测试和文件系统测试vdbanch
  14. 顺序表基本操作的实现
  15. 动态壁纸安卓_高清无水印!这4款壁纸软件,让你的手机好看又独特
  16. 欧盟要求谷歌美国站点也要执行“被遗忘权”
  17. 玩儿计算机最快的人,电脑玩吃鸡最全攻略,让你吃鸡快人一步
  18. 【本人秃顶程序员】Java程序员,你会选择25k的996还是18k的965?
  19. 创建IRP的相关内容
  20. 网关技术详解及常见网关对比

热门文章

  1. 奥蓝网络科技温馨提示:企业做新闻营销不能忽略以下几点
  2. 开源 - 学习笔记 - 青阳网络文件传输系统初体验
  3. CreateML 使用以及机器学习基础概念
  4. 设备指纹学习笔记和思考
  5. 虹科鹰眼系统将为职业棒球大联盟赋予全新意义
  6. 学校的论文查重可以查几次?
  7. python给出数据点进行插值_在Python中用“不动点”插值数据
  8. Flink大数据量调优思路总结(一)
  9. dpdk eal初始化流程梳理
  10. halcon把图片改成单一通道_图片的通道转换