微信小程序java后台解码获取信息

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34207892/article/details/79149863

微信小程序java后台解码获取信息

由于小程序开发多个地方都需要使用到解码获取信息的需求,但由于本人从事java的开发然后去官网下载的sdk中竟然没有java的。哎-_-。所以准备写一篇关于java解码的blog吧。

一、我们解码前需要获取到几个小程序前端传过来的数据
登录凭证code:调用wx.login()可以获得;
秘钥iv和需要解码的encryptedData字符串:这个根据自己项目的需求定了,比如:获取openid和unionid可以在 wx.getUserInfo()中获得iv和encryptedData。
如果获取微信群ID:则通过wx.getShareInfo()获得iv和encryptedData。
微信小程序前端这里就不做详细的分析了。

二 、 java后端的实现

/**
     * 获取微信群ID(Gid)
     * data:2018/1/24
     * @return
     * @throws Exception 
     */
    public String wxGetGroupGid() throws Exception{

        String code=request.getParameter("code");////接受小程序传过来的登录凭证code,
        String iv=request.getParameter("iv");
        String encryptedData=request.getParameter("encryptedData");
        String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret"
                + "=SECRET&js_code=JSCODE&grant_type=authorization_code";// 获取openid的地址
        String url = OPENID_URL.replace("APPID", Pkcs7Encoder.APPID)
                .replace("SECRET", Pkcs7Encoder.APPSECRET)
                .replace("JSCODE", code);
        JSONObject jsonObject = null;
        //向微信后台发起请求的url 
        jsonObject = Pkcs7Encoder.doGetStr(url);// 调取Get提交方法
        String session_key = jsonObject.getString("session_key");
        String result = Pkcs7Encoder.decrypt(encryptedData, session_key, iv,
                "UTF-8");

        JSONObject userInfoJSON = JSONObject.fromObject(result);
        String openGid=userInfoJSON.getString("openGId");
        System.out.println(openGid);
        String JData="{\"openGid\":\""+openGid+"\"}";
        //response.getWriter().write(openGid);
        Struts2Utils.renderJsonNoDown(response, JData); 
        return null;
    }

解码的帮助类

public class Pkcs7Encoder {
     public final static String APPID = "***";   //小程序的APPID
      public final static   String APPSECRET = "***"; //小程序的appsecret
     public final static String grant_type = "authorization_code";//授权(必填)
      // 算法名称
    static  final String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    static  final String algorithmStr = "AES/CBC/PKCS7Padding";
    private static Key key;
    private static Cipher cipher;
    boolean isInited = false;

    //默认对称解密算法初始向量 iv
    static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };


    public static String decrypt(String encryptedData, String sessionKey, String iv, String encodingFormat)
            throws Exception {
            // 被加密的数据
            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");
            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.fromObject(result).toString();
            }
            }catch (Exception e) {
                e.printStackTrace();
            }
            return null;
    }
    /**
     * 返回openid,unionid
     * @param url
     * @return
     */
    public static JSONObject doGetStr(String url){

        DefaultHttpClient httpClient = new DefaultHttpClient();

        HttpGet httpGet = new HttpGet(url);

        JSONObject jsonObject = null;

        try {
            HttpResponse response = httpClient.execute(httpGet);

            HttpEntity entity = response.getEntity();   //接受结果
            if(entity != null){
                String result = EntityUtils.toString(entity,"UTF-8");
                jsonObject = JSONObject.fromObject(result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public 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(algorithmStr, "BC");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 加密方法
     *      --使用默认iv时
     * @param content
     *            要加密的字符串
     * @param keyBytes
     *            加密密钥
     * @return
     */
    public static byte[] encrypt(byte[] content, byte[] keyBytes) {
        byte[] encryptedText =  encryptOfDiyIV(content,keyBytes,iv);
        return encryptedText;
    }


    /**
     * 解密方法
     *      --使用默认iv时
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @return
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
        byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv);
        return encryptedText;
    }
    /**
     * 加密方法
     *      ---自定义对称解密算法初始向量 iv
     * @param content
     *              要加密的字符串
     * @param keyBytes
     *              加密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return 加密的结果
     */
    public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(ivs));
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
    /**
     * 解密方法
     *
     * @param encryptedData
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @param ivs
     *         自定义对称解密算法初始向量 iv
     * @return
     */
    public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) {
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(ivs));
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
    /** 
* 向指定 URL 发送POST方法的请求 
*  
* @param url 发送请求的 URL 
* @param param 请求参数 
* @return 所代表远程资源的响应结果 
*/  
public static String sendPost(String url, Map<String, ?> paramMap) {  
     PrintWriter out = null;  
     BufferedReader in = null;  
     String result = "";  

     String param = "";  
Iterator<String> it = paramMap.keySet().iterator();  

while(it.hasNext()) {  
   String key = it.next();  
   param += key + "=" + paramMap.get(key) + "&";  
}  

     try {  
         URL realUrl = new URL(url);  
         // 打开和URL之间的连接  
         URLConnection conn = realUrl.openConnection();  
         // 设置通用的请求属性  
         conn.setRequestProperty("accept", "*/*");  
         conn.setRequestProperty("connection", "Keep-Alive");  
         conn.setRequestProperty("Accept-Charset", "utf-8");  
         conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
         // 发送POST请求必须设置如下两行  
         conn.setDoOutput(true);  
         conn.setDoInput(true);  
         // 获取URLConnection对象对应的输出流  
         out = new PrintWriter(conn.getOutputStream());  
         // 发送请求参数  
         out.print(param);  
         // flush输出流的缓冲  
         out.flush();  
         // 定义BufferedReader输入流来读取URL的响应  
         in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));  
         String line;  
         while ((line = in.readLine()) != null) {  
             result += line;  
         }  
     } catch (Exception e) {  
      e.printStackTrace();
     }  
     //使用finally块来关闭输出流、输入流  
     finally{  
         try{  
             if(out!=null){  
                 out.close();  
             }  
             if(in!=null){  
                 in.close();  
             }  
         }  
         catch(IOException ex){  
             ex.printStackTrace();  
         }  
     }  
     return result;  
 }  

}

只要涉及到小程序解码的都是通用的,所以到这里已经完成了。

展开阅读全文

没有更多推荐了,返回首页