Java实现微信对称解密算法获取小程序用户信息

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

ps:微信开放数据校验与解密

实现步骤方法如下:
  1. 导入加密包commons-codec,bcprov-jdk16(支持PKCS#7填充),Java默认支持PKCS5填充不支持PKCS#7填充
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</dependency>
<dependency>
        <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk16</artifactId>
    <version>1.46</version>
</dependency>

2.实现微信对称解密算法

/**
 * 编码格式
 */
private static final String ENCODING = "UTF-8";
/**
 * 加密算法
 */
public static final String KEY_ALGORITHM = "AES/CBC/PKCS7Padding";

public static String decryptUserInfo(String encryptedData,String iv,String sessionKey) {
    try {
        byte[] data = Base64.decodeBase64(encryptedData);
        byte[] aseKey = Base64.decodeBase64(sessionKey);
        byte[] ivData = Base64.decodeBase64(iv);
        // 如果密钥不足16位,那么就补足
        int base = 16;
        if (aseKey.length % base != 0) {
            int groups = aseKey.length / base + (aseKey.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(aseKey, 0, temp, 0, aseKey.length);
            aseKey = temp;
        }
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        SecretKeySpec spec = new SecretKeySpec(aseKey, "AES");
        AlgorithmParameters parameters = generateIv(ivData);
        cipher.init(Cipher.DECRYPT_MODE, spec,parameters);
        byte[] result = cipher.doFinal(data);
        return new String(result,ENCODING);
    } catch (Exception e) {
        throw new FinException(e.getMessage(),"500");
    }

}

public static AlgorithmParameters generateIv(byte[] iv) throws Exception{
    AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
    params.init(new IvParameterSpec(iv));
    return params;
}
遇到的坑:

始终解密不成功,原来是session_key没有刷新导致的,每次都是先通过code2session获取,然后再通过wx.login获取用户信息,导致session_key不是最新的,在wx.login回调成功后再次调用code2session获取session_key才解密成功。


image.png

推荐阅读更多精彩内容