加密對(duì)稱解密算法如下:
- 對(duì)稱解密使用的算法為 AES-128-CBC齐蔽,數(shù)據(jù)采用PKCS#7填充剑勾。
- 對(duì)稱解密的目標(biāo)密文為 Base64_Decode(encryptedData)。
- 對(duì)稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節(jié)雇寇。
- 對(duì)稱解密算法初始向量 為Base64_Decode(iv)氢拥,其中iv由數(shù)據(jù)接口返回。
實(shí)現(xiàn)步驟方法如下:
- 導(dǎo)入加密包c(diǎn)ommons-codec锨侯,bcprov-jdk16(支持PKCS#7填充)嫩海,Java默認(rèn)支持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.實(shí)現(xiàn)微信對(duì)稱解密算法
/**
* 編碼格式
*/
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位,那么就補(bǔ)足
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;
}
遇到的坑:
始終解密不成功囚痴,原來(lái)是session_key沒(méi)有刷新導(dǎo)致的叁怪,每次都是先通過(guò)code2session獲取,然后再通過(guò)wx.login獲取用戶信息深滚,導(dǎo)致session_key不是最新的奕谭,在wx.login回調(diào)成功后再次調(diào)用code2session獲取session_key才解密成功。
image.png