org.sdn.api.utils.Signature Maven / Gradle / Ivy
/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package org.sdn.api.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.sdn.api.constants.OpenApiConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 签名工具类
*
* @author gaosong
* @date 2018/10/15
*
*/
public class Signature {
private static Logger logger = LoggerFactory.getLogger(Signature.class);
/**
* 签名算法
*
* @param signstr
* 要参与签名的字符串
* @param key
* 签名的key
* @return 签名
* @throws Exception
*/
private static String sign(String signstr, String key) {
signstr += "&key=" + key;
signstr = MD5.encodeMD5(signstr).toUpperCase();
return signstr;
}
/**
* 签名
*
* @param
* @return 签名结果
*/
public static String getSign(Map params, String appSecret) {
return sign(JSON.toJSONString(params, SerializerFeature.MapSortField), appSecret);
}
/**
* 除去数组中的空值和签名参数sign
* @param params 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
/**
* 除去数组中的空值和签名参数sign
* @param params 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
public static Map paraFilter(Map params) {
Map result = new HashMap<>(16);
if (params == null || params.size() <= 0) {
return result;
}
for (String key : params.keySet()) {
Object value = params.get(key);
if (value == null || StringUtils.isEmpty(value)
|| key.equalsIgnoreCase(OpenApiConstants.SIGN) || value.equals("null")) {
continue;
}
if (value instanceof java.lang.Integer || value instanceof java.lang.Long) {
value = value.toString();
}
result.put(key, value);
}
return result;
}
/**
* 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param params 需要排序并参与字符拼接的参数组
* @return 拼接后字符串
*/
public static String createLinkString(Map params) {
List keys = new ArrayList(params.keySet());
Collections.sort(keys);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
Object value = params.get(key);
if (value instanceof java.util.List) {
value = JSONArray.toJSON(value);
} else if (value instanceof java.util.Date) {
Date date = (Date)value;
value = date.getTime();
} else {
value = JSONObject.toJSON(value);
}
if (value == null || StringUtils.isEmpty(value) || key.equalsIgnoreCase(OpenApiConstants.SIGN)) {
continue;
}
//拼接时,不包括最后一个&字符
if (i == keys.size() - 1) {
sb.append(key + "=" + value);
} else {
sb.append(key + "=" + value + "&");
}
}
return sb.toString();
}
/**
* 检验API返回的数据里面的签名是否合法,避免数据在传输的过程中被第三方篡改
*
* @param responseString
* API返回的JSON数据字符串
* @return API签名是否合法
*/
public static boolean checkIsSignValidFromResponseString(String responseString, String key) {
Map map = JSON.parseObject(responseString);
return checkSignValid(map, key);
}
/**
* 校验回调API返回的签名
*
* @param map
* @return
*/
public static boolean checkSignValid(Map map, String key) {
String signFromAPIResponse = map.get(OpenApiConstants.SIGN).toString();
if (signFromAPIResponse == "" || signFromAPIResponse == null) {
logger.info("checkSignValid() info={}","API返回的数据签名数据不存在,有可能被第三方篡改!!!");
return false;
}
/**清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名*/
map.remove("sign");
/**将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较*/
String signForAPIResponse = Signature.getSign(map, key);
if (!signForAPIResponse.equals(signFromAPIResponse)) {
/**签名验不过,表示这个API返回的数据有可能已经被篡改了*/
logger.info("checkSignValid() info={}","签名验证失败,有可能被第三方篡改!!!");
return false;
}
return true;
}
}