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

io.github.wslxm.springbootplus2.utils.XjSignUtil Maven / Gradle / Ivy

package io.github.wslxm.springbootplus2.utils;

import io.github.wslxm.springbootplus2.core.utils.XjPropUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 *  @author wangsong
 * 参数验证签名
 */
@Slf4j
public class XjSignUtil {

    private static String APP_KEY = null;
    private static String SECRET_KEY = null;
    private static Long TIME_OUT = null;
    // 默认值
    private final static String DEFAULT_APP_KEY = "xijia";
    private final static String DEFAULT_SECRET_KEY = "xijia@qwer";
    private final static Long DEFAULT_TIME_OUT = 60L;

    /**
     * 字符编码
     */
    private final static String INPUT_CHARSET = "UTF-8";
    /**
     * 验签 key
     */
    public final static String SIGN = "sign";
    /**
     * 时间戳 key
     */
    public final static String TIMESTAMP = "timestamp";
    /**
     * body 参数的参数key
     */
    public final static String BODY = "body";


    private static String getAppKey() {
        if (APP_KEY == null) {
            Object appKey = XjPropUtil.findByKey("secure.sign.appKey");
            APP_KEY = appKey != null ? appKey.toString() : DEFAULT_APP_KEY;
        }
        return APP_KEY;
    }

    private static String getSecretKey() {
        if (SECRET_KEY == null) {
            Object secretKey = XjPropUtil.findByKey("secure.sign.secretKey");
            SECRET_KEY = secretKey != null ? secretKey.toString() : DEFAULT_SECRET_KEY;
        }
        return SECRET_KEY;
    }

    private static Long getTimeOut() {
        if (TIME_OUT == null) {
            Object timeout = XjPropUtil.findByKey("secure.sign.timeout");
            TIME_OUT = timeout != null ? Long.parseLong(timeout.toString()) : DEFAULT_TIME_OUT;
        }
        return TIME_OUT;
    }


    /**
     * 根据反馈回来的信息,生成签名结果 current=1&fullName= &id=&size=10×tamp=1618538349587&username=
     *
     * @param params 通知返回来的参数数组
     * @return 验证结果
     */
    public static boolean verify(Map params) {
        // 获取签名参数
        boolean isVerify = false;
        String sign = "";
        if (params.containsKey(SIGN)) {
            sign = params.get(SIGN);
            // 过滤空值sign
            Map sParaNew = paraFilter(params);
            // 获取待签名字符串
            String preSignStr = createLinkString(sParaNew, false);
            log.debug("加签参数:{}", preSignStr);
            // 获得签名验证结果
            String mysign = XjSignMd5Util.md5(getAppKey() + preSignStr + getSecretKey());
            if (mysign.equals(sign)) {
                isVerify = true;
            }
        }
        return isVerify;
    }


    /**
     * 验证是否超时
     * timestamp = 请求时间(秒)
     *
     * @return 验证结果
     */
    public static boolean isTimeVerify(Long timestamp) {
        // 判断请求是否超时
        long currentTimeMillis = System.currentTimeMillis();
        return timestamp != null && (currentTimeMillis - Long.parseLong(timestamp.toString())) < (getTimeOut() * 1000L);
    }


    /**
     * 请求参数Map转换验证Map
     * 

* SignUtil.toVerifyMap(request.getParameterMap(), false); * 参数根据字母大小写排序 *

* * @param requestParams 请求参数Map * @param charset 是否要转utf8编码 * @return */ public static Map toVerifyMap(Map requestParams, boolean charset) { Map params = new HashMap<>(16); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { String name = (String) iter.next(); String[] values = requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 if (charset) { valueStr = getContentString(valueStr, INPUT_CHARSET); } params.put(name, valueStr); } return params; } /** * 除去数组中的空值和签名参数 * * @param sArray 签名参数组 * @return 去掉空值与签名参数后的新签名参数组 */ public static Map paraFilter(Map sArray) { Map result = new HashMap<>(16); if (sArray == null || sArray.size() <= 0) { return result; } for (String key : sArray.keySet()) { String value = sArray.get(key); //|| "".equals(value) if (value == null || key.equalsIgnoreCase(SIGN)) { continue; } result.put(key, value); } return result; } /** * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 * * @param params 需要排序并参与字符拼接的参数组 * @param encode 是否需要UrlEncode * @return 拼接后字符串 */ public static String createLinkString(Map params, boolean encode) { List keys = new ArrayList<>(params.keySet()); Collections.sort(keys); StringBuilder sb = new StringBuilder(""); for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = params.get(key); if (encode) { value = urlEncode(value, INPUT_CHARSET); } if (i == keys.size() - 1) { // 拼接时,不包括最后一个&字符 sb.append(key).append("=").append(value); } else { sb.append(key).append("=").append(value).append("&"); } } return sb.toString(); } /** * 编码转换 * * @param content * @param charset * @return * @throws UnsupportedEncodingException */ private static byte[] getContentBytes(String content, String charset) { if (charset == null || "".equals(charset)) { return content.getBytes(); } try { return content.getBytes(charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); } } /** * 编码转换 * * @param content * @param charset * @return */ private static String getContentString(String content, String charset) { if (charset == null || "".equals(charset)) { return new String(content.getBytes()); } try { return new String(content.getBytes("ISO-8859-1"), charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset); } } /** * URL转码 * * @param content * @param charset * @return */ private static String urlEncode(String content, String charset) { try { return URLEncoder.encode(content, charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy