All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy