微信小程序session_key解析中反斜杠问题处理 Java解析

Java服务端微信小程序解密用户信息、手机号需用到session_key也需要decode,以下是官方描述:

加密数据解密算法

接口如果涉及敏感数据(如wx.getUserInfo当中的 openId 和 unionId),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据(encryptedData) 进行对称解密。 解密算法如下:

  1. 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
  2. 对称解密的目标密文为 Base64_Decode(encryptedData)。
  3. 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
  4. 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。

 

Base64_Decode(session_key),用java.util包里的就可以:

import java.util.Base64;...byte[] keyByte = Base64.getDecoder().decode(sessionKey);...

  有时候用code获取到的session_key会有反斜杠,如:

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
{"session_key":"tErsom\/ZTDEkKZ1saEiX2w==","openid":""}

重点:对session_key只要转JSON格式,反斜杠就没有了,示例如下:

技术图片

 

 技术图片

 附上完整解析算法:

import com.alibaba.fastjson.JSONObject;import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.security.AlgorithmParameters;import java.security.Security;import java.util.Arrays;import java.util.Base64;/** * @description: * @author: ruJun * @create: 2020/5/9 10:08 */public class WXUtils { private volatile static BouncyCastleProvider bouncyCastleProvider = null; /** * @description: 解密小程序的用户信息,手机号加密数据 * @author: ruJun * @create: 2020/5/9 10:09 */ public static JSONObject decode(String encryptedData, String sessionKey, String iv) throws Exception { // 被加密的数据 byte[] dataByte = Base64.getDecoder().decode(encryptedData); // 加密秘钥 byte[] keyByte = Base64.getDecoder().decode(sessionKey); // 偏移量 byte[] ivByte = Base64.getDecoder().decode(iv); // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(getInstance()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, "UTF-8"); return JSONObject.parseObject(result); } return null; } public static BouncyCastleProvider getInstance() { if (bouncyCastleProvider == null) { synchronized (BouncyCastleProvider.class) { if (bouncyCastleProvider == null) { bouncyCastleProvider = new BouncyCastleProvider(); } } } return bouncyCastleProvider; }}

 

 

  

相关文章