加密对称解密算法如下:
- 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
- 对称解密的目标密文为 Base64_Decode(encryptedData)。
- 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
- 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
ps:微信开放数据校验与解密
实现步骤方法如下:
- 导入加密包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才解密成功。