收藏
回答

为什么在解密userinfo的时候会有部分乱码?

最近需要获取用户的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 个回答

  • 雪峰
    雪峰
    2020-04-15

    楼主解决了吗?我也遇到这个问题了json开头是乱码,后面正常,无法正常解析


    2020-04-15
    有用
    回复 8
    • 雪峰
      雪峰
      2020-04-15
      甚是苦恼啊
      2020-04-15
      回复
    • Song
      Song
      2020-04-20回复雪峰
      解决了,是我把iv搞错了,getuserinfo和login的
      2020-04-20
      回复
    • 雪峰
      雪峰
      2020-04-22回复Song
      不就getuserInfo有iv,login没有啊
      2020-04-22
      回复
    • Song
      Song
      2020-04-22回复雪峰
      我是微信调我后台方法那边参数给错了,wx.login和wx.getuserinfo先手顺序和参数你再检查一遍
      2020-04-22
      回复
    • 雪峰
      雪峰
      2020-04-22回复Song
      解决了  ,谢谢
      2020-04-22
      1
      回复
    查看更多(3)
  • Song
    Song
    2020-03-04
    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 Song
     * @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);
        }
    }
    
    2020-03-04
    有用
    回复
登录 后发表内容
问题标签