zoukankan      html  css  js  c++  java
  • 微信小程序 encryptedData 的解密(JAVA)

    上图为微信官方api提供的登陆获取用户信息的流程,session_key的得到这里不进行说明,详情可以看微信小程序的官方api。

    数据签名校验
    
    为了确保 开放接口 返回用户数据的安全性,微信会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。
    
    通过调用接口(如 wx.getUserInfo)获取数据时,接口会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )
    开发者将 signature、rawData 发送到开发者服务器进行校验。服务器利用用户对应的 session_key 使用相同的算法计算出签名 signature2 ,比对 signature 与 signature2 即可校验数据的完整性。
    

     

    以上描述即为  微信小程序传过来的 rawData  和 已经得到session_key进行sha1加密之后的值 如果和signature相等的话 就表明数据校验通过,

    加密数据解密算法
    
    接口如果涉及敏感数据(如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 )
    

    微信小程序会传来四个数据 其中两个为 rawData和 sighnature ,

    还有两个为  encryptedData 和 iv 

    encryptedData  session_key iv  这三个数据 经过特定的解密之后, 就可以得到用户信息了。

    解密的工具类:

    package cn.iyishuxy.common.utils;
    
    import com.alibaba.fastjson.JSONObject;
    import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.AlgorithmParameters;
    import java.security.Security;
    import java.util.Arrays;
    
    /**
     * @author ljh
     */
    public class WXUtils {
        public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv){
            // 被加密的数据
            byte[] dataByte = Base64.decode(encryptedData);
            // 加密秘钥
            byte[] keyByte = Base64.decode(sessionKey);
            // 偏移量
            byte[] ivByte = Base64.decode(iv);
    
            try {
                // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
                int base = 16;
                if (keyByte.length % base != 0) {
                    int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                    byte[] temp = new byte[groups * base];
                    Arrays.fill(temp, (byte) 0);
                    System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                    keyByte = temp;
                }
                // 初始化
                Security.addProvider(new BouncyCastleProvider());
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
                SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
                AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
                parameters.init(new IvParameterSpec(ivByte));
                cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
                byte[] resultByte = cipher.doFinal(dataByte);
                if (null != resultByte && resultByte.length > 0) {
                    String result = new String(resultByte, "UTF-8");
                    return JSONObject.parseObject(result);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

      

    需要注意的是 BouncyCastleProvider包 需要手动导入
    maven:
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.59</version>
    </dependency>
    

      

  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/handsomejunhong/p/8670367.html
Copyright © 2011-2022 走看看