微信小程序数据解密(Java 语言)
2023-09-27 14:23:43 时间
pom 依赖
非必须,hutool 是为了使用 AES 工具类,bcprov 是为了使用 PKCS7Padding,都可以自己实现,这里为了方便。
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <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; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.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 { KeyGenerator.getInstance(KEY_NAME).init(128); // 生成 iv // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为 0 // Arrays.fill(iv, (byte) 0x00); AlgorithmParameters ivj = AlgorithmParameters.getInstance(KEY_NAME); ivj.init(new IvParameterSpec(java.util.Base64.getDecoder().decode(iv))); // 生成解密 Key key = new SecretKeySpec(java.util.Base64.getDecoder().decode(sessionKey), KEY_NAME); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key, ivj); // 设置为解密模式 return cipher.doFinal(java.util.Base64.getDecoder().decode(encrypted)); } }
测试
public static void main(String[] args) { String appId = "wx4f4bc4dec97d474b"; String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJl" + "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)); }
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#加密数据解密算法
相关文章
- java实现基于IO流存取信息的【学生成绩管理系统】
- java里面的public static void main(String[] args)
- JVM性能优化, Part 5:Java的伸缩性
- 微信公众平台开发教程Java版(六) 事件处理(菜单点击/关注/取消关注)
- 《深入理解Java虚拟机》作者周志明带你了解:Graal VM-云原生时代的Java
- 2022年最新Java面试真题总结!
- 《备战金九银十》之Java基础夺命连环16问
- Java学习专栏!全网最牛!
- Java中的装箱和拆箱
- Java面试常考知识
- 34 异常机制 异常体系结构 Java把异常当做对象来处理 并定义一个基类java.lang.Throwable作为所有异常的超类 Error Exception
- java对接微信小程序
- 基Java(SSM)+MySQL框架的 JavaWeb 通用权限管理系统【100010078】
- java开发微信模板消息推送
- java服务端微信小程序支付
- java 控制线程
- Java中的微信支付(2):API V3 微信平台证书的获取与刷新
- Java中的微信支付(1):API V3版本签名详解
- java代码生成word目录
- java.util.ConcurrentModificationException 解决办法
- Java 代理(proxy)模式
- ES6中的Map集合(与java里类似)
- Java开发实现微信小程序支付(微信支付)
- 微信小程序 获取小程序码和二维码java接口开发
- Java提高篇(三):内部类和匿名内部类
- java基础—综合练习
- JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI)
- Java内存模型深度解析:总结--转
- 【java养成】:案例(批量操作文件功能、商城进货交易记录程序设计)