微信小程序用户隐私数据解密

我们在获取到小程序的加密数据后,首先做的是校验数据,校验通过后进行数据的解密

一、新建隐私数据解密工具类——WXBizDataUtil

/**
 * @Author: zp.wei
 * @DATE: 2020/7/7 14:47
 */
public class WXBizDataUtil {

    public static String illegalAesKey = "-41001";//非法密钥
    public static String illegalIv = "-41002";//非法初始向量
    public static String illegalBuffer = "-41003";//非法密文
    public static String decodeBase64Error = "-41004"; //解码错误
    public static String noData = "-41005"; //数据不正确

    private String appid;

    private String sessionKey;

    public WXBizDataCrypt(String appid, String sessionKey) {
        this.appid = appid;
        this.sessionKey = sessionKey;
    }

    /**
     * 检验数据的真实性,并且获取解密后的明文.
     *
     * @param encryptedData string 加密的用户数据
     * @param iv            string 与用户数据一同返回的初始向量
     * @return String 返回用户信息
     */
    public String decryptData(String encryptedData, String iv) {
        if (StringUtils.length(sessionKey) != 24) {
            return illegalAesKey;
        }
        // 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
        byte[] aesKey = Base64.decodeBase64(sessionKey);

        if (StringUtils.length(iv) != 24) {
            return illegalIv;
        }
        // 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
        byte[] aesIV = Base64.decodeBase64(iv);

        // 对称解密的目标密文为 Base64_Decode(encryptedData)
        byte[] aesCipher = Base64.decodeBase64(encryptedData);
        try {
            byte[] resultByte = AESUtil.decrypt(aesCipher, aesKey, aesIV);
            if (null != resultByte && resultByte.length > 0) {
                String userInfo = new String(resultByte, "UTF-8");
                JSONObject jsons = JSON.parseObject(userInfo);
                String id = jsons.getJSONObject("watermark").getString("appid");
                if (!StringUtils.equals(id, appid)) {
                    return illegalBuffer;
                }
                return userInfo;
            } else {
                return noData;
            }
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 根据微信数据和sessionkey生成用于校验的签名
     * 
     * rawData     微信数据
     * sessionKey  sessionkey
     */
    public static String getsignature2(String rawData, String sessionKey) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String stringASCII = rawData + sessionKey;
        String signature2 = null;
        try {
            //指定sha1算法
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(stringASCII.getBytes("UTF-8"));
            //获取字节数组
            byte messageDigest[] = digest.digest();
            // 创建 Hex 字符串
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
                signature2 = hexString.toString().toLowerCase();
            }
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
           throw e;
        }
        return signature2;
    }

}

二,新建AES解密工具类——AESUtil

/**
 * @Author: zp.wei
 * @DATE: 2020/7/7 14:48
 */
public class AESUtil {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * AES解密
     *
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte)
            throws InvalidAlgorithmParameterException {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");
            //生成iv
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);// 初始化
            return cipher.doFinal(content);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

二、在controller相关方法里调用该工具类下的 decryptData 方法,即下面代码所示

private JSONObject getUserInfo(String iv, String encryptedData, String sessionKey) {
        String userInfo = null;
        //解密数据
        try {
            WXBizDataCrypt biz = new WXBizDataCrypt(CommonConfig.appletAppID, sessionKey);
            userInfo = biz.decryptData(encryptedData, iv);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.parseObject(userInfo);
    }

最后获取到的 userInfo 就是解密后的用户隐私数据了

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序交互后端解密通常涉及到对用户数据进行解的操作。在微信小程序中,用户敏感数据通常会使用微信提供的加密函数进行加密,然后传输到后端。后端需要使用相应的解密算法,将加密的数据解密成原始数据。 具体的解密步骤如下: 1. 获取用户敏感数据和加密向量:在小程序中,可以通过 `wx.getUserInfo` 或 `wx.login` 等 API 获取用户的敏感数据和加密向量。敏感数据一般是通过 `encryptedData` 字段返回,加密向量一般是通过 `iv` 字段返回。 2. 获取解密密钥:解密密钥需要通过微信提供的接口获取,这个接口通常是在后端调用。具体的接口是 `https://api.weixin.qq.com/sns/jscode2session`,需要传入小程序的 AppID、AppSecret、登录时获取的 code 等参数,然后会返回一个 session_key,这个 session_key 是解密密钥。 3. 解密敏感数据:使用合适的解密算法(如 AES-128-CBC)以及解密密钥(即上一步获取的 session_key),将加密的敏感数据和加密向量进行解密操作,得到原始数据。 注意事项: - 解密操作一般是在后端完成,不建议将解密密钥暴露在前端环境中。 - 解密密钥的有效期一般比较短,需要及时刷新。 - 解密操作涉及到敏感数据,需要注意保护用户隐私数据安全。 以上是一个一般的解密流程,具体的实现方式可能会有所不同,可以根据自己的需求和情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值