⼩程序数据解密(Java语⾔)pom 依赖
⾮必须,hutool 是为了使⽤ AES ⼯具类,bcprov 是为了使⽤ PKCS7Padding,都可以⾃⼰实现,这⾥为了⽅便。<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
入门的java游戏小程序<version>${hutool-all.version}</version>
</dependency>
<dependency><!--AES/CBC/PKCS7Padding-->
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>${bcprov-jdk15to18.version}</version>
</dependency>
⼯具类
import cn.hutool.json.JSONUtil;
pto.*;
pto.spec.IvParameterSpec;
pto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
public class WeChatUtil {
static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 初始化密钥
}
/**
* 解密数据
*/
public static String decrypt(String appId, String sessionKey, String encryptedData, String iv) throws
InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException,
NoSuchAlgorithmException, InvalidParameterSpecException, BadPaddingException, InvalidKeyException { // AES aes = new AES("CBC", "PKCS7Padding", Base64.decode(sessionKey), Base64.decode(iv));
// byte[] resultByte = aes.decrypt(Base64.decode(encryptedData));
byte[] resultByte = wxDecrypt(encryptedData, sessionKey, iv);
String result = new String(resultByte, StandardCharsets.UTF_8);
// 是否与当前 appid 相同
if (!appId.equals(JSONUtil.parseObj(result).getJSONObject("watermark").getStr("appid"))) {
result = "";
}
return result;
}
public static final String KEY_NAME = "AES"; // 算法名
// 加解密算法/模式/填充⽅式,ECB 模式只⽤密钥即可对数据进⾏加密解密,CBC 模式需要添加⼀个 iv
public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
/**
* 接⼝如果涉及敏感数据(如 wx.getUserInfo 当中的 openId 和 unionId),接⼝的明⽂内容将不包含这些敏感数据。
* 开发者如需要获取敏感数据,需要对接⼝返回的加密数据(encryptedData) 进⾏对称解密。解密算法如下:
* * 对称解密使⽤的算法为 AES-128-CBC,数据采⽤ PKCS#7 填充。
* * 对称解密的⽬标密⽂为 Base64_Decode(encryptedData)。
* * 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
* * 对称解密算法初始向量为 Base64_Decode(iv),其中 iv 由数据接⼝返回。
*
* @param encrypted ⽬标密⽂
* @param sessionKey 会话ID
* @param iv 加密算法的初始向量
*/
public static byte[] wxDecrypt(String encrypted, String sessionKey, String iv) throws NoSuchAlgorithmException,
InvalidParameterSpecException, NoSuchPaddingException, BadPaddingException, InvalidKeyException,
IllegalBlockSizeException, InvalidAlgorithmParameterException {
// ⽣成 iv
// iv 为⼀个 16 字节的数组,这⾥采⽤和 iOS 端⼀样的构造⽅法,数据全为 0
// Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters ivj = Instance(KEY_NAME);
ivj.init(new IvParameterSpec(java.Decoder().decode(iv)));
// ⽣成解密
Key key = new SecretKeySpec(java.Decoder().decode(sessionKey), KEY_NAME);
Cipher cipher = Instance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, ivj); // 设置为解密模式
return cipher.doFinal(java.Decoder().decode(encrypted));
}
}
测试
public static void main(String[] args) {
String appId = "wx4f4bc4dec97d474b";
String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTy
aGS9uT5geRa0W4oTOb1WT7fJl" +
"AC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW" + "1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs" +
"8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2" +
"SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COw" +
"fneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==";
String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";
String iv = "r7BXXKkLb8qrSNn05n0qiA==";
System.out.println(WeChatUtil.decrypt(appId, sessionKey, encryptedData, iv));
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论