牛骨文教育服务平台(让学习变的简单)
博文笔记

有关小程序的JAVA后台解密encryptedData获取openid及用户信息

创建时间:2017-10-11 投稿人: 浏览次数:1114

先贴上工具类,可获取openid及session_key,session_key在解密时会用到,这里还需要用到几个jar包
bouncycastle-jce-jdk13-112.jar
xfire-core-1.2.6.jar
百度搜一下就有
GetOpenid.java获取信息工具类

package com.hongbao.utils;

import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;

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;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.codehaus.xfire.util.Base64;

import net.sf.json.JSONObject;
/**
 * 
 * @author silen
 *  获取微信信息工具类
 */
public class GetOpenid {
    String appid = "wxd81c8f4c18******";
    String secret = "7bebc83146c9979ce08d22f244******";
    //可获取openid及session_key,其实这里openid不需要获取,encryptedData解密后包含openid
    public String get(String js_code) throws Exception {
        //官方接口,需要自己提供appid,secret和js_code
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+js_code+"&grant_type=authorization_code";
        //HttpRequestor是一个网络请求工具类,贴在了下面
        String oppid = new HttpRequestor().doGet(requestUrl);
        JSONObject oppidObj = JSONObject.fromObject(oppid);
        String openid = (String) oppidObj.get("openid");
        String session_key = (String) oppidObj.get("session_key");
        return session_key;
    }
    /**
     * 获取信息
     */
    public 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.fromObject(result);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }
}

网络请求工具类,在使用官方提供的接口获取信息的时候使用,在上面的类中已经有使用方法,很简单
HttpRequestor.java

package com.hongbao.utils;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;


public class HttpRequestor {
     private String charset = "utf-8";
        private Integer connectTimeout = null;
        private Integer socketTimeout = null;
        private String proxyHost = null;
        private Integer proxyPort = null;

        /**
         * Do GET request
         * @param url
         * @return
         * @throws Exception
         * @throws IOException
         */
        public String doGet(String url) throws Exception {

            URL localURL = new URL(url);

            URLConnection connection = openConnection(localURL);
            HttpURLConnection httpURLConnection = (HttpURLConnection)connection;

            httpURLConnection.setRequestProperty("Accept-Charset", charset);
            httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            InputStream inputStream = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader reader = null;
            StringBuffer resultBuffer = new StringBuffer();
            String tempLine = null;

            if (httpURLConnection.getResponseCode() >= 300) {
                throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
            }

            try {
                inputStream = httpURLConnection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
                reader = new BufferedReader(inputStreamReader);

                while ((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                }

            } finally {

                if (reader != null) {
                    reader.close();
                }

                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }

                if (inputStream != null) {
                    inputStream.close();
                }

            }

            return resultBuffer.toString();
        }

        /**
         * Do POST request
         * @param url
         * @param parameterMap
         * @return
         * @throws Exception 
         */
        public String doPost(String url, Map parameterMap) throws Exception {

            /* Translate parameter map to parameter date string */
            StringBuffer parameterBuffer = new StringBuffer();
            if (parameterMap != null) {
                Iterator iterator = parameterMap.keySet().iterator();
                String key = null;
                String value = null;
                while (iterator.hasNext()) {
                    key = (String)iterator.next();
                    if (parameterMap.get(key) != null) {
                        value = (String)parameterMap.get(key);
                    } else {
                        value = "";
                    }

                    parameterBuffer.append(key).append("=").append(value);
                    if (iterator.hasNext()) {
                        parameterBuffer.append("&");
                    }
                }
            }

            System.out.println("POST parameter : " + parameterBuffer.toString());

            URL localURL = new URL(url);

            URLConnection connection = openConnection(localURL);
            HttpURLConnection httpURLConnection = (HttpURLConnection)connection;

            httpURLConnection.setDoOutput(true);
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setRequestProperty("Accept-Charset", charset);
            httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterBuffer.length()));

            OutputStream outputStream = null;
            OutputStreamWriter outputStreamWriter = null;
            InputStream inputStream = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader reader = null;
            StringBuffer resultBuffer = new StringBuffer();
            String tempLine = null;

            try {
                outputStream = httpURLConnection.getOutputStream();
                outputStreamWriter = new OutputStreamWriter(outputStream);

                outputStreamWriter.write(parameterBuffer.toString());
                outputStreamWriter.flush();

                if (httpURLConnection.getResponseCode() >= 300) {
                    throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
                }

                inputStream = httpURLConnection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream);
                reader = new BufferedReader(inputStreamReader);

                while ((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                }

            } finally {

                if (outputStreamWriter != null) {
                    outputStreamWriter.close();
                }

                if (outputStream != null) {
                    outputStream.close();
                }

                if (reader != null) {
                    reader.close();
                }

                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }

                if (inputStream != null) {
                    inputStream.close();
                }

            }

            return resultBuffer.toString();
        }

        private URLConnection openConnection(URL localURL) throws IOException {
            URLConnection connection;
            if (proxyHost != null && proxyPort != null) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
                connection = localURL.openConnection(proxy);
            } else {
                connection = localURL.openConnection();
            }
            return connection;
        }

        /**
         * Render request according setting
         * @param request
         */
        private void renderRequest(URLConnection connection) {

            if (connectTimeout != null) {
                connection.setConnectTimeout(connectTimeout);
            }

            if (socketTimeout != null) {
                connection.setReadTimeout(socketTimeout);
            }

        }

        /*
         * Getter & Setter
         */
        public Integer getConnectTimeout() {
            return connectTimeout;
        }

        public void setConnectTimeout(Integer connectTimeout) {
            this.connectTimeout = connectTimeout;
        }

        public Integer getSocketTimeout() {
            return socketTimeout;
        }

        public void setSocketTimeout(Integer socketTimeout) {
            this.socketTimeout = socketTimeout;
        }

        public String getProxyHost() {
            return proxyHost;
        }

        public void setProxyHost(String proxyHost) {
            this.proxyHost = proxyHost;
        }

        public Integer getProxyPort() {
            return proxyPort;
        }

        public void setProxyPort(Integer proxyPort) {
            this.proxyPort = proxyPort;
        }

        public String getCharset() {
            return charset;
        }

        public void setCharset(String charset) {
            this.charset = charset;
        }
}

controller,这里就是工具类的使用方法了,没什么难度,简单的调用

// 获取信息
    @ResponseBody
    @RequestMapping("getOpenid")
    public void getOpenid(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        //需要使用小程序传过来的js_code获取session_key
        String js_code = request.getParameter("js_code");
        //这个就是要解密的东西--用户敏感信息加密数据
        String encryptedData = request.getParameter("encryptedData");
        //加密算法的初始向量
        String iv = request.getParameter("iv");
        //调用工具类中获取session_key的方法
        String sessionkey = new GetOpenid().get(js_code);
        //调用工具类中的解密方法,然后返回给小程序就OK了
        JSONObject obj = new GetOpenid().getUserInfo(encryptedData, sessionkey,
                iv);
        Gson gson = new Gson();
        String json = gson.toJson(obj);
        PrintWriter pw = response.getWriter();
        pw.write(json);
        pw.close();
    }

最后是小程序端的请求代码

var that = this
    wx.login({
      success: function (res) {
        if (res.code) {
          wx.getUserInfo({
            success: datas => {
              wx.request({
                url: that.baseurl + "getOpenid",
                data: {
                  js_code: res.code,
                  encryptedData: datas.encryptedData,
                  iv: datas.iv
                },
                header: {
                  "content-type": "application/json"
                },
                success: function (e) {
                  console.log(e.data)
                }
              })
            }
          })
        }
        else {
          console.log("获取用户登录态失败!" + res.errMsg)
        }
      }
    })

大功告成!!!

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。