为什么在解密userinfo的时候会有部分乱码?
发布于 19 天前 作者 minfeng 5324 次浏览 最后一次编辑是 18 天前 来自 问答

最近需要获取用户的unionid,就从getuserinfo接口去解密encryptedData,但是解密出来的字符串有部分乱码,用户信息是正确的,unionid也是正确的,watermark也对,就是openid是乱码的,我也是比对了之前获取到的openid之后才看出来这个是openid的,不知道大家有没有遇到过这种问题。

encryptedData:Q/4uaGK0CvLzgLbTGRRLEIGyyUOLOpirR7WFqQN4uytif2DwSLbfmrh3c+tM1x+XWaL7b3J++Jzf4MVWoOKJJtOZoM5svsIPbD3lk+5E5QXFvMnLzxyBzdH0LM207R00/+Pc+CWbjglxr7Li3osOetlw1QMW6LkiWta6fIqFbwqyMmugYHfEyBdXke7Wyim8OVG2oMghehhzIFn/oBXCDGb6Eh/r3QZoiBcTsKrJ7cRMiObcxbJj11t+j2xWO/CWRukbDagLhTEurEuz6nWwBaYQNlYObAg2/zsYtHNeDOzo5G+etkBIGHeO9FJaj/nXPP9Szvo2tVowXMTfxC4TbwIN1oclRalFhd6S1SROh5cQLYcAH2O0vPefT7L54r7QlQHFiw6U2QVaJs5WLyARmX1MERs6T/ScI+05xDQT2XGB8I0XNdPnfq5nvAwo0E1i1jqO8t5QPwTpct89odVbpFh61p6LIWkGZPEcHkhuFMmvIospjT6Z7kXZeAienpR3EFRZ1F2anCCqazDG3YP3aQ==
iv:p66r+AVpi5ad2nCRV3kdAA==
sessionkey:p66r+AVpi5ad2nCRV3kdAA==
appid:wxced7e28049a9178f

之前获取login接口获取的openid为 oKyDs4smEWoNDnwrBO-ONIONwxEA

解密后的数据如下:
MW��ͅ��������4smEWoNDnwrBO-ONIONwxEA","nickName":"Song","gender":1,"language":"zh_CN","city":"杭州","province":"浙江","country":"中国","avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/PiajxSqBRaEJudLUiaaZjjlFwJibhcyEHsG96a9jGf7xV3dfJKp7FXAHkguhvLTfNWia00FXqhbdeZxIX3E16gPGibQ/132","unionId":"oN-wmxLXfXSwewwyxzvdnk_DBlVE","watermark":{"timestamp":1583293045,"appid":"wxced7e28049a9178f"}}

就前面部分是乱码,但是破坏了整个json字符串。。。
2 回复
package com.macro.mall.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;

/**
 * 微信解密算法
 * https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#%E5%8A%A0%E5%AF%86%E6%95%B0%E6%8D%AE%E8%A7%A3%E5%AF%86%E7%AE%97%E6%B3%95
 * [@author](/user/author) Song
 * [@create](/user/create) 2020-03-03 10:58
 */
public class WXBizDataCryptUtil {
    // 算法名
    public static final String KEY_NAME = "AES";
    // 加解密算法/模式/填充方式
    // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
    public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";

    /**
     * 1.对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
     * 2.对称解密的目标密文为 Base64_Decode(encryptedData)。
     * 3.对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
     * 4.对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
     *
     * @param encryptedData
     * @param iv
     * @param sessionKey
     * @return
     */
    public static JSONObject wxDecrypt(String encryptedData, String iv, String sessionKey){
        String json = null;
        byte[] encrypted64 = Base64.decodeBase64(encryptedData);
        byte[] key64 = Base64.decodeBase64(sessionKey);
        byte[] iv64 = Base64.decodeBase64(iv);
        try {
            init();
            json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
            System.out.println(json);
        } catch (Exception e) {
            System.out.println("解密微信失败:" + e.getMessage());
        }
        return JSONObject.parseObject(json);
    }

    /**
     * 初始化密钥
     */
    public static void init() throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        KeyGenerator.getInstance(KEY_NAME).init(128);
    }

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

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

是你解密代码的问题,我没遇到过

回到顶部