You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
5.7 KiB
179 lines
5.7 KiB
2 years ago
|
package com.ynxbd.wx.wxfactory.utils;
|
||
|
|
||
|
import com.ynxbd.common.helper.common.ErrorHelper;
|
||
|
import com.ynxbd.common.helper.common.JsonHelper;
|
||
|
import org.apache.commons.codec.binary.Hex;
|
||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||
|
|
||
|
import javax.crypto.Mac;
|
||
|
import javax.crypto.spec.SecretKeySpec;
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import java.io.InputStream;
|
||
|
import java.io.InputStreamReader;
|
||
|
import java.nio.charset.StandardCharsets;
|
||
|
import java.text.ParsePosition;
|
||
|
import java.text.SimpleDateFormat;
|
||
|
import java.util.Date;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Map;
|
||
|
|
||
|
public class WxSignHelper {
|
||
|
// 签名类型
|
||
|
final public static String SIGN_TYPE_MD5 = "MD5";
|
||
|
final public static String SIGN_TYPE_HMAC_SHA256 = "HMAC-SHA256";
|
||
|
|
||
|
// 时间标识
|
||
|
final public static String DATE_KEY = "date";
|
||
|
final public static String TIME_KEY = "time";
|
||
|
|
||
|
|
||
|
/**
|
||
|
* 签名生成
|
||
|
*
|
||
|
* @param map map
|
||
|
* @param signType 类型
|
||
|
* @param key 密钥
|
||
|
* @return t | f
|
||
|
*/
|
||
|
public static String generateSign(Map<String, Object> map, String signType, String key) {
|
||
|
try {
|
||
|
Map<String, Object> orderMap = MapHelper.order(map);
|
||
|
orderMap.remove("sign");
|
||
|
|
||
|
String paramsStr = MapHelper.mapJoin(orderMap, false, false);
|
||
|
if (signType == null) {
|
||
|
signType = SIGN_TYPE_MD5;
|
||
|
}
|
||
|
if (SIGN_TYPE_HMAC_SHA256.equalsIgnoreCase(signType)) {
|
||
|
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
||
|
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
||
|
sha256_HMAC.init(secret_key);
|
||
|
return Hex.encodeHexString(sha256_HMAC.doFinal((paramsStr + "&key=" + key).getBytes(StandardCharsets.UTF_8))).toUpperCase();
|
||
|
} else {
|
||
|
return DigestUtils.md5Hex(paramsStr + "&key=" + key).toUpperCase();
|
||
|
}
|
||
|
} catch (Exception e) {
|
||
|
ErrorHelper.println(e);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* 签名验证
|
||
|
*
|
||
|
* @param map map
|
||
|
* @param key 密钥
|
||
|
* @return t | f
|
||
|
*/
|
||
|
public static boolean validateSign(Map<String, Object> map, String key) {
|
||
|
return map.get("sign") != null && map.get("sign").equals(generateSign(map, null, key));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 签名验证
|
||
|
*
|
||
|
* @param map map
|
||
|
* @param key 密钥
|
||
|
* @return t | f
|
||
|
*/
|
||
|
public static boolean validateSign(Map<String, Object> map, String sign_type, String key) {
|
||
|
return map.get("sign") != null && map.get("sign").equals(generateSign(map, sign_type, key));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 从请求流中获取数据
|
||
|
*
|
||
|
* @param request 请求
|
||
|
* @return map
|
||
|
*/
|
||
|
public static String getReqData(HttpServletRequest request) {
|
||
|
// 获取请求数据
|
||
|
try (InputStream in = request.getInputStream();) {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
|
||
|
char[] buffer = new char[4096];
|
||
|
int len;
|
||
|
while ((len = reader.read(buffer)) != -1) {
|
||
|
sb.append(buffer, 0, len);
|
||
|
}
|
||
|
String respData = sb.toString();
|
||
|
if ("".equals(respData)) {
|
||
|
return null;
|
||
|
}
|
||
|
return respData;
|
||
|
} catch (Exception e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 从请求中获取xml数据并转换为map
|
||
|
*
|
||
|
* @param request 请求
|
||
|
* @return map
|
||
|
*/
|
||
|
public static Map<String, Object> getReqXmlParamsMap(HttpServletRequest request) {
|
||
|
String reqXml = getReqData(request);
|
||
|
if (reqXml == null) {
|
||
|
return null;
|
||
|
}
|
||
|
return XmlHelper.xmlOuterToMap(reqXml, false);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 从请求中获取xml数据并转换为对象
|
||
|
*
|
||
|
* @param request 请求
|
||
|
* @return 对象
|
||
|
*/
|
||
|
public static <T> T getReqXmlToBean(HttpServletRequest request ,Class<T> clazz) {
|
||
|
Map<String, Object> paramsMap = getReqXmlParamsMap(request);
|
||
|
if (paramsMap == null) {
|
||
|
return null;
|
||
|
}
|
||
|
return JsonHelper.parseObject(JsonHelper.toJsonString(paramsMap), clazz);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 解析腾讯返回的时间
|
||
|
*
|
||
|
* @param timeEnd 时间
|
||
|
* @return map
|
||
|
*/
|
||
|
public static Map<String, String> getDateMap(String timeEnd) {
|
||
|
Map<String, String> dateMap = new HashMap<>();
|
||
|
|
||
|
ParsePosition pos = new ParsePosition(0);
|
||
|
Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(timeEnd, pos);
|
||
|
|
||
|
dateMap.put(DATE_KEY, new SimpleDateFormat("yyyy-MM-dd").format(date));
|
||
|
dateMap.put(TIME_KEY, new SimpleDateFormat("HH:mm:ss").format(date));
|
||
|
return dateMap;
|
||
|
}
|
||
|
|
||
|
|
||
|
public static String getMapInfo(Map<String, Object> paramsMap, String... ignored) {
|
||
|
StringBuilder info = new StringBuilder();
|
||
|
boolean isIgnore;
|
||
|
for (String key : paramsMap.keySet()) {
|
||
|
isIgnore = false;
|
||
|
if (ignored != null) {
|
||
|
for (String item : ignored) {
|
||
|
if (item.equals(key)) {
|
||
|
isIgnore = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (isIgnore) {
|
||
|
continue;
|
||
|
}
|
||
|
info.append(key).append("=").append(paramsMap.get(key)).append(";"); // 拼接微信返回的信息
|
||
|
}
|
||
|
return info.toString();
|
||
|
}
|
||
|
|
||
|
}
|