E企盈营销工具技术服务商 热线:4006-838-530

微信小程序加密消息解密工具类

E企盈直播平台营销卖货系统

开发者后台校验与解密开放数据微信会对这些开放数据做签名和加密处理。开发者后台拿到开放数据后可以对数据进行校验签名和解密,来保证数据不被篡改。签名校验以及数据加解密涉及用户的会话密钥 session_key。 开发者应该事先通过 wx.login 登录流程获取会话密钥 session_key 并保存在服务器。为了数据不被篡改,开发者不应该把 session_key 传到小程序客户端等服务器外的环境。数据签名校验为了确保开放接口返回用户数据的安全性,微信会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。通过调用接口(如 wx.getUserInfo)获取数据时,接口会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )开发者将 signature、rawData 发送到开发者服务器进行校验。服务器利用用户对应的 session_key 使用相同的算法计算出签名 signature2 ,比对 signature 与 signature2 即可校验数据的完整性。如 wx.getUserInfo的数据校验:接口返回的rawData:加密数据解密算法接口如果涉及敏感数据(如wx.getUserInfo当中的 openId 和 unionId),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据(encryptedData) 进行对称解密。 解密算法如下:对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。对称解密的目标密文为 Base64_Decode(encryptedData)。对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。微信官方提供了多种编程语言的示例代码。每种语言类型的接口名字均一致。调用方式可以参照示例。另外,为了应用能校验数据的有效性,会在敏感数据加上数据水印( watermark )watermark参数说明:参数类型说明appidString敏感数据归属 appId,开发者可校验此参数与自身 appId 是否一致timestampInt敏感数据获取的时间戳, 开发者可以用于数据时效性校验如接口 wx.getUserInfo 敏感数据当中的 watermark:{    “openId”: “OPENID”,    “nickName”: “NICKNAME”,    “gender”: GENDER,    “city”: “CITY”,    “province”: “PROVINCE”,    “country”: “COUNTRY”,    “avatarUrl”: “AVATARURL”,    “unionId”: “UNIONID”,    “watermark”:    {        “appid”:”APPID”,        “timestamp”:TIMESTAMP    }}注:解密后得到的json数据根据需求可能会增加新的字段,旧字段不会改变和删减,开发者需要预留足够的空间会话密钥 session_key 有效性开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的 session_key。微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。首先使用code换取session_key  登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。请求地址GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code请求参数属性类型默认值必填说明appidstring 是小程序 appIdsecretstring 是小程序 appSecretjs_codestring 是登录时获取的 codegrant_typestring 是授权类型,此处只需填写 authorization_code返回值Object返回的 JSON 数据包属性类型说明openidstring用户唯一标识session_keystring会话密钥unionidstring用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见 UnionID 机制说明。errcodenumber错误码errmsgstring错误信息errcode 的合法值值说明最低版本-1系统繁忙,此时请开发者稍候再试 0请求成功 40029code 无效 45011频率限制,每个用户每分钟100次获取sessionKey之后就可以解密了package com.water.elephant.utils;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.Arrays;import org.bouncycastle.util.encoders.Base64;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.security.Key;import java.security.Security;/** * 微信工具类 */public class WechatUtil {    public static String decryptData(String encryptDataB64, String sessionKeyB64, String ivB64) throws Exception {        return new String(                decryptOfDiyIV(                        Base64.decode(encryptDataB64),                        Base64.decode(sessionKeyB64),                        Base64.decode(ivB64)                )        );    }    private static final String KEY_ALGORITHM = “AES”;    private static final String ALGORITHM_STR = “AES/CBC/PKCS7Padding”;    private static Key key;    private static Cipher cipher;    private static void init(byte[] keyBytes) {        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要        int base = 16;        if (keyBytes.length % base != 0) {            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);            byte[] temp = new byte[groups * base];            Arrays.fill(temp, (byte) 0);            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);            keyBytes = temp;        }        // 初始化        Security.addProvider(new BouncyCastleProvider());        // 转化成JAVA的密钥格式        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);        try {            // 初始化cipher            cipher = Cipher.getInstance(ALGORITHM_STR, “BC”);        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 解密方法     *     * @param encryptedData 要解密的字符串     * @param keyBytes      解密密钥     * @param ivs           自定义对称解密算法初始向量 iv     * @return 解密后的字节数组     */    private static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes, byte[] ivs) {        byte[] encryptedText = null;        init(keyBytes);        try {            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));            encryptedText = cipher.doFinal(encryptedData);        } catch (Exception e) {            e.printStackTrace();        }        return encryptedText;    }}

赞(0) 打赏
未经允许不得转载:E企盈小程序开发-热线:4006-838-530 » 微信小程序加密消息解密工具类
分享到: 更多 (0)
E企盈小程序直播营销卖货系统
E企盈直播平台营销卖货系统

评论 抢沙发

E企盈小程序开发

联系我们联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏