注冊用戶即可下載全站資源 關注Java幫幫微信公眾號
 

JAVA版微信小程序用戶數據的簽名驗證和加解密

65
發表時間:2018-11-09 13:20


簽名驗證和加解密

數據簽名校驗

為了確保 開放接口 返回用戶數據的安全性,微信會對明文數據進行簽名。開發者可以根據業務需要對數據包進行簽名校驗,確保數據的完整性。

  • 簽名校驗算法涉及用戶的session_key,通過 wx.login 登錄流程獲取用戶session_key,并自行維護與應用自身登錄態的對應關系。

  • 通過調用接口(如 wx.getUserInfo)獲取數據時,接口會同時返回 rawData、signature,其中 signature = sha1( rawData + session_key )

  • 日本韩国三级aⅴ在线观看開發者將 signature、rawData 發送到開發者服務器進行校驗。服務器利用用戶對應的 session_key 使用相同的算法計算出簽名 signature2 ,比對 signature 與 signature2 即可校驗數據的完整性。

加密數據解密算法

日本韩国三级aⅴ在线观看接口如果涉及敏感數據(如wx.getUserInfo當中的 openId 和unionId ),接口的明文內容將不包含這些敏感數據。開發者如需要獲取敏感數據,需要對接口返回的加密數據( encryptedData )進行對稱解密。解密算法如下:

  • 日本韩国三级aⅴ在线观看對稱解密使用的算法為 AES-128-CBC,數據采用PKCS#7填充。

  • 日本韩国三级aⅴ在线观看對稱解密的目標密文為 Base64_Decode(encryptedData),

  • 日本韩国三级aⅴ在线观看對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節

  • 對稱解密算法初始向量 iv 會在數據接口中返回。

微信官方提供了多種編程語言的示例代碼(),但就是沒提供JAVA版本的,可能的確PHP是最好的語言,騰訊提供的demo好多都是PHP版本的。

JAVA代碼案例

日本韩国三级aⅴ在线观看pom.xml引入以下依賴:

<dependency>    <groupId>commons-codec</groupId>    <artifactId>commons-codec</artifactId>    <version>1.10</version></dependency><dependency>    <groupId>com.alibaba</groupId>    <artifactId>fastjson</artifactId>    <version>1.2.7</version></dependency><dependency>    <groupId>org.bouncycastle</groupId>    <artifactId>bcprov-jdk15on</artifactId>    <version>1.57</version></dependency>

我們可以參考PHP給出的代碼,使用JAVA實現:
AESUtil:

import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.AlgorithmParameters;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Security;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;/** * AES解密 */publicclassAESUtil{        static {        Security.addProvider(new BouncyCastleProvider());    }    /**     * AES解密     * @param content 密文     * @return     * @throws InvalidAlgorithmParameterException     * @throws NoSuchProviderException     */publicstaticbyte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte)            throws InvalidAlgorithmParameterException {        try {            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");            Key sKeySpec = new SecretKeySpec(keyByte, "AES");            //生成iv            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");            params.init(new IvParameterSpec(ivByte));            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);// 初始化return cipher.doFinal(content);        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        } catch (NoSuchPaddingException e) {           e.printStackTrace();        } catch (InvalidKeyException e) {            e.printStackTrace();        } catch (IllegalBlockSizeException e) {           e.printStackTrace();        } catch (BadPaddingException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }        returnnull;    }}

WXBizDataCrypt:

import java.io.UnsupportedEncodingException;import java.security.InvalidAlgorithmParameterException;import org.apache.commons.codec.binary.Base64;import org.apache.commons.lang.StringUtils;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;/** * 對微信小程序用戶加密數據的解密 */publicclassWXBizDataCrypt{        publicstatic String illegalAesKey = "-41001";//非法密鑰        publicstatic String illegalIv = "-41002";//非法初始向量        publicstatic String illegalBuffer = "-41003";//非法密文        publicstatic String decodeBase64Error = "-41004"; //解碼錯誤        publicstatic String noData = "-41005"; //數據不正確        private String appid;        private String sessionKey;    publicWXBizDataCrypt(String appid, String sessionKey){        this.appid = appid;        this.sessionKey = sessionKey;    }    /**     * 檢驗數據的真實性,并且獲取解密后的明文.     * @param encryptedData  string 加密的用戶數據     * @param iv  string 與用戶數據一同返回的初始向量     * @return data string 解密后的原文     * @return String 返回用戶信息     */public String decryptData(String encryptedData, String iv){        if (StringUtils.length(sessionKey) != 24) {            return illegalAesKey;        }        // 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節。byte[] aesKey = Base64.decodeBase64(sessionKey);        if (StringUtils.length(iv) != 24) {            return illegalIv;        }       // 對稱解密算法初始向量 為Base64_Decode(iv),其中iv由數據接口返回。byte[] aesIV = Base64.decodeBase64(iv);       // 對稱解密的目標密文為 Base64_Decode(encryptedData)byte[] aesCipher = Base64.decodeBase64(encryptedData);        try {            byte[] resultByte = AESUtil.decrypt(aesCipher, aesKey, aesIV);            if (null != resultByte && resultByte.length > 0) {                String userInfo = new String(resultByte, "UTF-8");                JSONObject jsons = JSON.parseObject(userInfo);                String id = jsons.getJSONObject("watermark").getString("appid");                if (!StringUtils.equals(id, appid)) {                    return illegalBuffer;                }                return userInfo;            } else {                return noData;            }        } catch (InvalidAlgorithmParameterException e) {            e.printStackTrace();        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        returnnull;    }    /**     * encryptedData 和 iv 兩個參數通過小程序wx.getUserInfo()方法獲取     * @param args     * @see     */publicstaticvoidmain(String[] args){        String appId = "wx4f4bc4dec97d474b";        String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";        String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM"                + "QmRzooG2xrDcvSnxIMXFufNstNGTyaGS"                + "9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+"                + "3hVbJSRgv+4lGOETKUQz6OYStslQ142d"                + "NCuabNPGBzlooOmB231qMM85d2/fV6Ch"                + "evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6"                + "/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw"                + "u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn"                + "/Hz7saL8xz+W//FRAUid1OksQaQx4CMs"                + "8LOddcQhULW4ucetDf96JcR3g0gfRK4P"                + "C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB"                + "6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns"                + "/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd"                + "lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV"                + "oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG"                + "20f0a04COwfneQAGGwd5oa+T8yO5hzuy"                + "Db/XcxxmK01EpqOyuxINew==";        String iv = "r7BXXKkLb8qrSNn05n0qiA==";        WXBizDataCrypt biz = new WXBizDataCrypt(appId, sessionKey);        System.out.println(biz.decryptData(encryptedData, iv));    }}

運行main方法,獲取返回結果:

{"openId":"oGZUI0egBJY1zhBYw2KhdUfwVJJE","nickName":"Band","gender":1,"language":"zh_CN","city":"Guangzhou","province":"Guangdong","country":"CN","avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0","unionId":"ocMvos6NjeKLIBqg5Mr9QjxrP1FA","watermark":{"timestamp":1477314187,"appid":"wx4f4bc4dec97d474b"}}


支付寶贊助-Java幫幫社區
微信贊助-Java幫幫社區
Java幫幫公眾號生態

Java幫幫公眾號生態

總有一款適合你

Java幫幫-微信公眾號

Java幫幫-微信公眾號

將分享做到極致

Python幫幫-公眾號

Python幫幫-公眾號

人工智能,爬蟲,學習教程

大數據驛站-微信公眾號

大數據驛站-微信公眾號

一起在數據中成長

九點編程-公眾號

九點編程-公眾號

深夜九點學編程

程序員生活志-公眾號

程序員生活志-公眾號

互聯網,職場,程序員那些事兒

Java幫幫學習群生態

Java幫幫學習群生態

總有一款能幫到你

Java學習群

Java學習群

與大牛一起交流

大數據學習群

大數據學習群

在數據中成長

九點編程學習群

九點編程學習群

深夜九點學編程

python學習群

python學習群

人工智能,爬蟲

測試學習群

測試學習群

感受測試的魅力

Java幫幫生態承諾

Java幫幫生態承諾

一直堅守,不負重望

初心
勤儉
誠信
正義
分享
合作品牌 非盈利生態-優質內容分享傳播者
關于我們
友鏈申請
友鏈交換:加幫主QQ2524138991 留言即可 24小時內答復  
全站內容非商業用途,內容來源于網友,并遵循 許可,如有異議請聯系客服。
會員登錄
獲取驗證碼
登錄
登錄
我的資料
留言
回到頂部