package org.springblade.modules.signature.util;
|
import org.apache.commons.lang3.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springblade.common.utils.HttpClientUtils;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.IOException;
|
import java.io.UnsupportedEncodingException;
|
import java.security.GeneralSecurityException;
|
import java.security.MessageDigest;
|
import java.util.*;
|
|
/**
|
* sign 生成工具类
|
* @author zhongrj
|
* @since 2022-03-11
|
*/
|
public class SignUtil {
|
|
private static Logger LOGGER = LoggerFactory.getLogger(SignUtil.class);
|
|
|
/**
|
* 获取签名sign
|
* @param params 参数集合不含appSecret
|
* @param secret 验证接口的appSecret
|
* @return
|
*/
|
public static String getSign(Map params,String secret)
|
{
|
String sign="";
|
StringBuilder sb = new StringBuilder();
|
//1. 先对请求参数排序
|
Set<String> keyset=params.keySet();
|
TreeSet<String> sortSet=new TreeSet<>();
|
sortSet.addAll(keyset);
|
Iterator<String> it=sortSet.iterator();
|
//2. 把参数的key value链接起来 ,再把appSecret拼接参数字符串的最后面,得到要加密的字符串
|
while(it.hasNext())
|
{
|
String key=it.next();
|
String value=params.get(key).toString();
|
sb.append(key).append(value);
|
}
|
sb.append(secret);
|
byte[] md5Digest;
|
try {
|
//3. Md5加密
|
md5Digest = getMD5Digest(sb.toString());
|
//4.得到sign
|
sign = byte2hex(md5Digest);
|
} catch (IOException e) {
|
LOGGER.error("生成签名错误",e);
|
}
|
// 5. 返回 sign
|
return sign;
|
}
|
|
|
/**
|
* 回调接口验证签名方法
|
* @param request
|
* @return
|
*/
|
public static Boolean checkSign(HttpServletRequest request,String appSecret){
|
Boolean flag= false;
|
String sign = request.getParameter("sign");//签名
|
if(StringUtils.isEmpty(sign)){
|
return false;
|
}
|
//检查sign是否过期
|
Enumeration<?> pNames = request.getParameterNames();
|
Map<String, String> params = new HashMap<>();
|
while (pNames.hasMoreElements()) {
|
String pName = (String) pNames.nextElement();
|
if("sign".equals(pName)) {
|
continue;
|
}
|
String pValue = request.getParameter(pName);
|
params.put(pName, pValue);
|
}
|
if(sign.equals(getSign(params, appSecret))){
|
flag = true;
|
}
|
return flag;
|
}
|
|
/**
|
* MD5加密数据方法
|
*/
|
private static byte[] getMD5Digest(String data) throws IOException {
|
byte[] bytes = null;
|
try {
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
bytes = md.digest(data.getBytes("UTF-8"));
|
} catch (GeneralSecurityException gse) {
|
throw new IOException(gse);
|
}
|
return bytes;
|
}
|
|
/**
|
* MD5加密数据后的数据处理方法
|
*/
|
private static String byte2hex(byte[] bytes) {
|
StringBuilder sign = new StringBuilder();
|
for (int i = 0; i < bytes.length; i++) {
|
String hex = Integer.toHexString(bytes[i] & 0xFF);
|
if (hex.length() == 1) {
|
sign.append("0");
|
}
|
sign.append(hex.toUpperCase());
|
}
|
return sign.toString();
|
}
|
|
|
|
public static String utf8Encoding(String value, String sourceCharsetName) {
|
try {
|
return new String(value.getBytes(sourceCharsetName), "UTF-8");
|
} catch (UnsupportedEncodingException e) {
|
throw new IllegalArgumentException(e);
|
}
|
}
|
|
/**
|
测试方法
|
*/
|
public static void main(String[] args)
|
{
|
//参数签名算法测试例子
|
HashMap<String, String> signMap = new HashMap<String, String>();
|
String appkey = "584561146";
|
signMap.put("appKey",appkey);
|
|
// System.out.println("得到签名sign1:"+getSign(signMap,"454sd5fa45dsa5fdaf54"));
|
String sign = getSign(signMap, "454sd5fa45dsa5fdaf54");
|
signMap.put("sign",sign);
|
HttpClientUtils.postParams("http://localhost:81/attendance/AppSave", appkey, signMap);
|
}
|
}
|