JAVA解密微信小程序用户信息encryptedData方案

JAVA解密微信小程序用户信息encryptedData方案

首先我相信当各位大佬看到这个文章的时候,应该看过很多关于java解密微信小程序用户信息的方案了。

但是总会遇到一些问题,比如代码复制过来,导入正确的包也会遇到的问题拉~,这里我就发布一个自己遇到的问题,希望能帮助后面的人,这个坑很大哦~

废话不多说,贴代码

这个AES解密工具包,放在Util包下

import java.security.AlgorithmParameters;
import java.security.Key;
import java.util.Arrays;
import java.util.Base64;
import java.util.Base64.Decoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public final class AES {

    public static final String KEY_ALGORITHM = "AES";
    public static final String CIPHER_ALGORITHM = "AES/CBC/NoPadding";

    // 生成密钥
    public static byte[] generateKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGenerator.init(128);
        SecretKey key = keyGenerator.generateKey();
        return key.getEncoded();
    }

    // 生成iv
    public static AlgorithmParameters generateIV() throws Exception {
        // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
        byte[] iv = new byte[16];
        Arrays.fill(iv, (byte) 0x00);

        return generateIV(iv);
    }

    // 生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
        AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_ALGORITHM);
        params.init(new IvParameterSpec(iv));
        return params;
    }

    // 转化成JAVA的密钥格式
    public static Key convertToKey(byte[] keyBytes) throws Exception {
        SecretKey secretKey = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        return secretKey;
    }

    // 加密
    public static byte[] encrypt(byte[] data, byte[] keyBytes, AlgorithmParameters iv) throws Exception {
        // 转化为密钥
        Key key = convertToKey(keyBytes);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        return cipher.doFinal(data);
    }

    // 解密
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv) throws Exception {
        Key key = convertToKey(keyBytes);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        return cipher.doFinal(encryptedData);
    }
}

调用方式

Decoder decoder = Base64.getDecoder();
        try {
            byte[] result = AES.decrypt(decoder.decode(encryptedData), decoder.decode(session_key),
                    AES.generateIV(decoder.decode(iv)));
            String s=StringUtils.toString(result,"UTF-8");
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();

        }

那么当你走到这一步的时候,你很可能遇到的问题:
这里写图片描述

java.lang.IllegalArgumentException: Illegal base64 character 20

没错就是这个异常,问题的原因是因为 encryptedData 密文在进行http传输的时候按照W3C的规范给你把其中的+号变成了空格,

例如这个密文

TuuTLtXibxWa1L8uTBQciO4hah/LwFh95Ip8I/tNo1FbDlEbIk0USXr4d3mm91XaVZ7+CynILJcCih5bbSEcFJKQiua2yn48Fdu4WiXRKwU0RD49aldpZ9SGSU+AtzAsD3KbyUiStdfwaWhkeX37qnQeXucV0/irhZBkwFqg5EXHDvq+cOldXl6pVJt2oO3/4c0kBECfGavQ717QXKJLqnEaoDfh8Qfce678CeDwa6wYnR46Xu6fnBx5t0K53f5qKL9hZZtHlr28aFZ6kYVq06mEP+97E4HxDBZjU9ZuDZjKyIpcajA2GUKCgzqqwMQG7iYfl6br7Q2cjh6UFGs5p08Ofr/p9TPNPXJm0ErAfVghu5UuyVxGRerW2O9aEQjKdlUGztlGqMZVriky6TjpzVz/Uy7m4++B7Pd4cvWkYaZGDWb+MdwMP+KYXLGVwrQyhPuAcppQqZ9G92qeMZl4uMfFLwFO3B/+7ShE0Ulpies=

然后通过DEBUG查看后台接收到的密文

TuuTLtXibxWa1L8uTBQciO4hah/LwFh95Ip8I/tNo1FbDlEbIk0USXr4d3mm91XaVZ7 CynILJcCih5bbSEcFJKQiua2yn48Fdu4WiXRKwU0RD49aldpZ9SGSU AtzAsD3KbyUiStdfwaWhkeX37qnQeXucV0/irhZBkwFqg5EXHDvq cOldXl6pVJt2oO3/4c0kBECfGavQ717QXKJLqnEaoDfh8Qfce678CeDwa6wYnR46Xu6fnBx5t0K53f5qKL9hZZtHlr28aFZ6kYVq06mEP 97E4HxDBZjU9ZuDZjKyIpcajA2GUKCgzqqwMQG7iYfl6br7Q2cjh6UFGs5p08Ofr/p9TPNPXJm0ErAfVghu5UuyVxGRerW2O9aEQjKdlUGztlGqMZVriky6TjpzVz/Uy7m4  B7Pd4cvWkYaZGDWb MdwMP KYXLGVwrQyhPuAcppQqZ9G92qeMZl4uMfFLwFO3B/ 7ShE0Ulpies=

两个仔细对比一下,然后你感到惊喜了吗?特瞄的居然是把+号改成了空格。

所以各位在前台传输数据的时候一定要注意,可以把+号改成 %2B 这样后台在接收密文的时候,按照规范来讲%2B会自动变成+号了。

恭喜出坑

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
获取微信小程序用户信息,您需要使用微信开发者工具中提供的API。具体步骤如下: 1. 在小程序中引入微信登录模块 ``` const app = getApp() wx.login({ success: res => { if (res.code) { // 发起网络请求,获取用户信息 wx.request({ url: 'https://yourdomain.com/onLogin', data: { code: res.code } }) } else { console.log('登录失败!' + res.errMsg) } } }) ``` 2. 在后端服务器上实现登录接口,用于获取用户的 openId 和 session_key ``` router.post('/onLogin', async (ctx, next) => { const { code } = ctx.request.body const appid = 'yourAppid' const secret = 'yourSecret' const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code` try { const res = await axios.get(url) const { openid, session_key } = res.data // 保存用户信息 // ... ctx.body = { openid, session_key } } catch (err) { console.error(err) } }) ``` 3. 在小程序获取用户信息 ``` wx.getUserInfo({ success: res => { const { userInfo } = res // 发送用户信息到后端服务器 wx.request({ url: 'https://yourdomain.com/onUserInfo', data: { openid: app.globalData.openid, session_key: app.globalData.session_key, userInfo } }) }, fail: err => { console.error(err) } }) ``` 4. 在后端服务器上实现获取用户信息接口,用于解密用户信息并保存 ``` router.post('/onUserInfo', async (ctx, next) => { const { openid, session_key, userInfo } = ctx.request.body const pc = new WXBizDataCrypt(appid, session_key) const data = pc.decryptData(userInfo.encryptedData, userInfo.iv) // 保存用户信息 // ... }) ``` 以上是一个简单的获取微信小程序用户信息的流程,具体实现方式可能因项目需求而有所不同。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值