最近需要获取用户的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字符串。。。
楼主解决了吗?我也遇到这个问题了json开头是乱码,后面正常,无法正常解析
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); } }