package com.kidgrow.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.kidgrow.common.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020
*
* @Description:
* @Project:
* @CreateDate: Created in 2020/2/4 14:00
* @Author: liuke
*/
@Slf4j
public class SignatureUtils {
/**
* 5分钟有效期
*/
private final static long MAX_EXPIRE = 5 * 60;
public static void main(String[] args) throws Exception {
String clientSecret = "0osTIhce7uPvDKHz6aa67bhCukaKoYl4";
//参数签名算法测试例子
HashMap signMap = new HashMap();
signMap.put("APP_ID", "1552274783265");
signMap.put("SIGN_TYPE", SignType.SHA256.name());
signMap.put("TIMESTAMP", DateUtils.getCurrentTimestampStr());
signMap.put("NONCE",RandomValueUtils.randomAlphanumeric(16));
String sign = SignatureUtils.getSign(signMap, clientSecret);
System.out.println("签名结果:" + sign);
signMap.put("SIGN", sign);
System.out.println("签名参数:" + JSONObject.toJSONString(signMap));
System.out.println(SignatureUtils.validateSign(signMap, clientSecret));
}
/**
* 验证参数
*
* @param paramsMap
* @throws Exception
*/
public static void validateParams(Map paramsMap) throws Exception {
Assert.hasText(paramsMap.get(CommonConstant.SIGN_APP_ID_KEY), "签名验证失败:APP_ID不能为空");
Assert.hasText(paramsMap.get(CommonConstant.SIGN_TIMESTAMP_KEY), "签名验证失败:TIMESTAMP不能为空");
Assert.hasText(paramsMap.get(CommonConstant.SIGN_SIGN_KEY), "签名验证失败:SIGN不能为空");
String timestamp = paramsMap.get(CommonConstant.SIGN_TIMESTAMP_KEY);
Long clientTimestamp = Long.parseLong(timestamp);
Long currentTimestamp = System.currentTimeMillis()/1000;
if ((currentTimestamp - clientTimestamp) > MAX_EXPIRE) {
throw new IllegalArgumentException("签名验证失败:TIMESTAMP已过期");
}
}
/**
* @param paramsMap 必须包含
* @param appid
* @return
*/
public static boolean validateSign(Map paramsMap, String appid) {
try {
validateParams(paramsMap);
String sign = paramsMap.get(CommonConstant.SIGN_SIGN_KEY);
//重新生成签名
String signNew = getSign(paramsMap, appid);
//判断当前签名是否正确
if (signNew.equals(sign)) {
return true;
}
} catch (Exception e) {
log.error("validateSign error:{}", e.getMessage());
return false;
}
return false;
}
/**
* 得到签名
*
* @param paramMap 参数集合不含appSecret
* 必须包含appId=客户端ID
* signType = SHA256|MD5 签名方式
* timestamp=时间戳
* nonce=随机字符串
* @param appid 验证接口的clientSecret
* @return
*/
public static String getSign(Map paramMap, String appid) {
if (paramMap == null) {
return "";
}
//排序
Set keySet = paramMap.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(CommonConstant.SIGN_SIGN_KEY)) {
continue;
}
if (paramMap.get(k).trim().length() > 0) {
// 参数值为空,则不参与签名
sb.append(paramMap.get(k).trim());
}
}
String signStr = signStr = EncryptUtils.md5Hex(sb.toString()).toLowerCase();
return signStr;
}
public enum SignType {
MD5,
SHA256;
public static boolean contains(String type) {
for (SignType typeEnum : SignType.values()) {
if (typeEnum.name().equals(type)) {
return true;
}
}
return false;
}
}
}