admin
2022-03-29 fac5d01bfcddfc8edef0a5fd3d401b1fe383fe16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package org.yeshi.utils.wx;
 
import java.io.InputStream;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.entity.wx.WXAPPInfo;
import org.yeshi.utils.entity.wx.WXMPSessionInfo;
import org.yeshi.utils.entity.wx.WXMPUserInfo;
 
import com.google.gson.Gson;
 
import net.sf.json.JSONObject;
 
public class WXXCXUtil {
 
    public static InputStream getXCXCode(String accessToken, String path, String scene) {
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
        JSONObject data = new JSONObject();
        data.put("scene", scene);
        data.put("page", path);
        // JSONObject color = new JSONObject();
        // color.put("r", );
        // color.put("g", );
        // color.put("b", );
        //
        // data.put("line_color", color);
 
        try {
            return HttpUtil.postForInputstream(url, data.toString());
        } catch (Exception e) {
            return null;
        }
    }
 
    // 获取有限的小程序码
    public static InputStream getLimitXCXCode(String accessToken, String path) {
        String url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken;
        JSONObject data = new JSONObject();
        data.put("path", path);
        data.put("width", 500);
        return HttpUtil.postForInputstream(url, data.toString());
    }
 
    public static WXMPSessionInfo getSessionInfo(WXAPPInfo app, String code) {
        try {
            String url = String.format(
                    "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                    app.getAppId(), app.getAppSecret(), code);
            String result = HttpUtil.get(url);
            System.out.println(result);
            JSONObject json = JSONObject.fromObject(result);
            WXMPSessionInfo info = new WXMPSessionInfo(json.optString("openid"), json.optString("session_key"),
                    json.optString("unionid"));
            if (org.yeshi.utils.StringUtil.isNullOrEmpty(info.getOpenId()))
                return null;
            return info;
        } catch (Exception e) {
        }
        return null;
    }
 
    /**
     * 通过解密信息获取电话号码
     * 
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public static String getPhoneNumber(String sessionKey, String encryptedData, String iv) {
        String result = decrpt(sessionKey, encryptedData, iv);
        if (!org.yeshi.utils.StringUtil.isNullOrEmpty(result)) {
            JSONObject data = JSONObject.fromObject(result);
            if (data.optString("countryCode").equalsIgnoreCase("86"))// 只能获取中国的手机号
                return data.optString("purePhoneNumber");
        }
        return null;
    }
 
    /**
     * 获取用户信息
     * 
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public static WXMPUserInfo getUserInfo(String sessionKey, String encryptedData, String iv) {
        String result = decrpt(sessionKey, encryptedData, iv);
        if (!org.yeshi.utils.StringUtil.isNullOrEmpty(result)) {
            WXMPUserInfo userInfo = new Gson().fromJson(result, WXMPUserInfo.class);
            return userInfo;
        }
        return null;
    }
 
    private static String decrpt(String sessionKey, String encryptedData, String iv) {
        try {
            final Base64 base64 = new Base64();
            // 被加密的数据
            byte[] dataByte = base64.decode(encryptedData.getBytes("UTF-8"));
            // 加密秘钥
            byte[] keyByte = base64.decode(sessionKey.getBytes("UTF-8"));
            // 偏移量
            byte[] ivByte = base64.decode(iv.getBytes("UTF-8"));
 
            // 如果密钥不足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 result;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return null;
 
    }
 
}