package com.boco.nbd.wios.wx.weixin; import com.boco.nbd.wios.manage.util.SpringContextUtil; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; /** * @author yong */ @Component public class WeixinSignUtils { private static String weixinAppId; @Value("${weixin.appId}") public void setWeixinAppId(String appId){ WeixinSignUtils.weixinAppId = appId; } private static String weixinAppSecret; @Value("${weixin.appSecret}") public void setWeixinAppSecret(String appSecret){ WeixinSignUtils.weixinAppSecret = appSecret; } private static String h5Url; @Value("${url.h5}") public void setH5Url(String h5Url){ WeixinSignUtils.h5Url = h5Url; } private final static String token = "cams_wios"; /** * 获取当前url * 当前网页的URL,不包含#及其后面部分 * @return */ private static String getUrl(){ HttpServletRequest request = SpringContextUtil.getRequest(); String url = request.getRequestURL().toString(); if(StringUtils.isNotBlank(h5Url)) { url=h5Url+"/"; } String queryString = request.getQueryString(); if(StringUtils.isNotEmpty(queryString)){ return url +"?"+queryString; } return url; } /** * 获取随机码 * @return */ private static String create_nonce_str() { return UUID.randomUUID().toString(); } /** * 获取时间戳 * @return */ private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } public static Map<String, String> sign(String jsapi_ticket, String url) { Map<String, String> ret = new HashMap<>(8); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String str; String signature = ""; //注意这里参数名必须全部小写,且必须有序 str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(str.getBytes(StandardCharsets.UTF_8)); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsapi_ticket); ret.put("nonceStr", nonce_str); ret.put("timestamp", timestamp); ret.put("signature", signature); return ret; } public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] { token, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典序排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } public static Map<String, String> getParam(){ String ticket=WeixinHelper.getJsapiTicket(weixinAppId, weixinAppSecret); String url=getUrl(); Map<String, String> result=sign(ticket, url); result.put("appId", weixinAppId); return result; } }