WechatUtil.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package com.happy.common.util;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. // vo实体类参数
  5. import com.happy.Model.weixin.CodeEntityVo;
  6. import com.happy.Model.weixin.WeiXinUtil;
  7. import org.bouncycastle.util.encoders.Base64;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.apache.http.util.TextUtils;
  10. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  11. import org.springframework.stereotype.Component;
  12. import javax.crypto.Cipher;
  13. import javax.crypto.spec.IvParameterSpec;
  14. import javax.crypto.spec.SecretKeySpec;
  15. import javax.imageio.ImageIO;
  16. import java.awt.image.BufferedImage;
  17. import java.io.*;
  18. import java.net.HttpURLConnection;
  19. import java.net.URL;
  20. import java.net.URLConnection;
  21. import java.security.AlgorithmParameters;
  22. import java.security.Security;
  23. import java.util.*;
  24. public class WechatUtil {
  25. /**
  26. * 获取小程序code换取openid、session_key
  27. *
  28. * @param code
  29. * @return
  30. */
  31. public static JSONObject getOpenId(String code) {
  32. String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WeiXinUtil.appid_c
  33. + "&secret=" + WeiXinUtil.screct_c + "&js_code=" + code + "&grant_type=authorization_code";
  34. PrintWriter out = null;
  35. BufferedReader in = null;
  36. String line;
  37. StringBuffer stringBuffer = new StringBuffer();
  38. try {
  39. URL realUrl = new URL(url);
  40. // 打开和URL之间的连接
  41. URLConnection conn = realUrl.openConnection();
  42. // 设置通用的请求属性 设置请求格式
  43. //设置返回类型
  44. conn.setRequestProperty("contentType", "text/plain");
  45. //设置请求类型
  46. conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
  47. //设置超时时间
  48. conn.setConnectTimeout(1000);
  49. conn.setReadTimeout(1000);
  50. conn.setDoOutput(true);
  51. conn.connect();
  52. // 获取URLConnection对象对应的输出流
  53. out = new PrintWriter(conn.getOutputStream());
  54. // flush输出流的缓冲
  55. out.flush();
  56. // 定义BufferedReader输入流来读取URL的响应 设置接收格式
  57. in = new BufferedReader(
  58. new InputStreamReader(conn.getInputStream(), "UTF-8"));
  59. while ((line = in.readLine()) != null) {
  60. stringBuffer.append(line);
  61. }
  62. JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
  63. return jsonObject;
  64. } catch (Exception e) {
  65. e.printStackTrace();
  66. }
  67. //使用finally块来关闭输出流、输入流
  68. finally {
  69. try {
  70. if (out != null) {
  71. out.close();
  72. }
  73. if (in != null) {
  74. in.close();
  75. }
  76. } catch (IOException ex) {
  77. ex.printStackTrace();
  78. }
  79. }
  80. return null;
  81. }
  82. /**
  83. * 在上面的代码中我们已经获取到了openid和session_key了,而code信息中是不能获取到用户的手机号码的,
  84. * 解析微信手机号的相关数据需要openid和session_key才行,所以在上面代码中,我将相关数据返回给了前端,
  85. * 前端将我传回的参数,还有第二次请求中的iv、encryptedData一起传回给后端,然后我们进行解密
  86. * **/
  87. public static Map<String, Object> getPhoneNumber(CodeEntityVo vo,String openid,String session_key) {
  88. Map<String,Object> map=new HashMap<>();
  89. if (openid!=null) {
  90. if(session_key==null){
  91. return null;
  92. }
  93. map.put("openid",openid);
  94. // 被加密的数据
  95. byte[] dataByte = Base64.decode(vo.getEncryptedData());
  96. // 加密秘钥
  97. byte[] keyByte = Base64.decode(session_key);
  98. // 偏移量
  99. byte[] ivByte = Base64.decode(vo.getIv());
  100. try {
  101. // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
  102. int base = 16;
  103. String result = null;
  104. if (keyByte.length % base != 0) {
  105. int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
  106. byte[] temp = new byte[groups * base];
  107. Arrays.fill(temp, (byte) 0);
  108. System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
  109. keyByte = temp;
  110. }
  111. // 初始化
  112. Security.addProvider(new BouncyCastleProvider());
  113. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
  114. SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
  115. AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
  116. parameters.init(new IvParameterSpec(ivByte));
  117. // 初始化
  118. cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
  119. byte[] resultByte = cipher.doFinal(dataByte);
  120. if (null != resultByte && resultByte.length > 0) {
  121. result = new String(resultByte, "UTF-8");
  122. JSONObject jsonObject = JSONObject.parseObject(result);
  123. map.put("param",jsonObject);
  124. return map;
  125. }
  126. } catch (Exception e) {
  127. e.printStackTrace();
  128. }
  129. }
  130. return null;
  131. }
  132. }