1. 程式人生 > 其它 >聽說你用java解析小程式session_key遇到問題了!

聽說你用java解析小程式session_key遇到問題了!

技術標籤:微信開發

微信推出了小程式,很多公司的客戶端應用不僅具有了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);