聽說你用java解析小程式session_key遇到問題了!
阿新 • • 發佈:2020-12-09
技術標籤:微信開發
微信推出了小程式,很多公司的客戶端應用不僅具有了APP、H5、還接入了小程式開發。但是,小程式中竟然沒有提供Java版本的加密資料解密演算法。這著實讓廣大的Java開發人員蛋疼。
最新微信小程式開放資料校驗與解密連結
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
微信官方提供了多種程式語言的示例程式碼C++,Node,python,php 就是木有java!!!
以下只貼出部分關鍵程式碼,這是最終版,也是正確的版本
//依賴 <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency>
//AES解密演算法類 /** * 微信小程式 對稱資料解密演算法 */ public class WxBizDecryptUtils { // 演算法名 public static final String KEY_NAME = "AES"; /** * 微信 資料解密<br/> * 對稱解密使用的演算法為 AES-128-CBC,資料採用PKCS#7填充 * 對稱解密的目標密文:encrypted=Base64_Decode(encryptData) * 對稱解密祕鑰:key = Base64_Decode(session_key),aeskey是16位元組 * 對稱解密演算法初始向量:iv = Base64_Decode(iv),同樣是16位元組 * * @param encrypted 需要解密的密文(前端提供) * @param session_key 會話祕鑰 * @param iv 加密演算法的初始向量(前端提供) */ public String wxDecrypt(String encrypted, String session_key, String iv) { String json = null; byte[] encrypted64 = Base64.decodeBase64(encrypted); byte[] key64 = Base64.decodeBase64(session_key); byte[] iv64 = Base64.decodeBase64(iv); try { init(); json = new String(decrypt(encrypted64, key64, generateIV(iv64))); } catch (Exception e) { e.printStackTrace(); } return json; } /** * 初始化金鑰 */ private void init() throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); KeyGenerator.getInstance(KEY_NAME).init(128); } /** * 生成iv */ private AlgorithmParameters generateIV(byte[] iv) throws Exception { // iv 為一個 16 位元組的陣列,這裡採用和 iOS 端一樣的構造方法,資料全為0 // Arrays.fill(iv, (byte) 0x00); AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME); params.init(new IvParameterSpec(iv)); return params; } /** * 生成解密 */ private byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv) throws Exception { Key key = new SecretKeySpec(keyBytes, KEY_NAME); // // 加解密演算法/模式/填充方式 // // ECB模式只用金鑰即可對資料進行加密解密,CBC模式需要新增一個iv Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); // 設定為解密模式 cipher.init(Cipher.DECRYPT_MODE, key, iv); return cipher.doFinal(encryptedData); }
//呼叫
//注意 encryptedData和iv是需要前端傳過來的,分別是需要解密的密文和解密向量
WxBizDecryptUtils wxBizDecryptUtils =new WxBizDecryptUtils();
String result = wxBizDecryptUtils.wxDecrypt(encryptedData, sessionkey, iv);