| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- package com.railway.common.utils.sign;
- import static com.railway.common.core.domain.dto.ReturnCode.SIGN_CHECK_FAIL;
- import com.railway.common.core.domain.AjaxResult;
- import com.railway.common.core.domain.dto.ReturnCode;
- import com.railway.common.utils.DateUtils;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
- import java.time.LocalDateTime;
- import java.util.Arrays;
- import java.util.Map;
- import javax.crypto.Mac;
- import javax.crypto.spec.SecretKeySpec;
- import javax.xml.bind.DatatypeConverter;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- /**
- * 接口签名检查
- *
- * @author zhaomn
- */
- @Slf4j
- public class SignatureUtil {
- public static final String STR_TIMESTAMP = "timestamp";
- public static final String STR_SIGNATURE = "signature";
- public static final long MAX_TIME_DIFF = 600L;
- private static final String ENCODING = "UTF-8";
- private static final String HMAC_SHA256 = "HmacSHA256";
- public static String getParamString(Map<String, String> paramMap)
- throws UnsupportedEncodingException {
- if (paramMap == null || paramMap.isEmpty()) {
- return "";
- }
- // 对参数进行排序
- String[] sortedKeys = paramMap.keySet().toArray(new String[]{});
- Arrays.sort(sortedKeys);
- final String SEPARATOR = "&";
- // 生成stringToSign字符串
- StringBuilder stringToSign = new StringBuilder();
- StringBuilder canonicalizedQueryString = new StringBuilder();
- boolean isFirst = true;
- for (String key : sortedKeys) {
- if (isFirst) {
- isFirst = false;
- } else {
- canonicalizedQueryString.append(SEPARATOR);
- }
- // 这里注意对key和value进行编码
- canonicalizedQueryString.append(percentEncode(key)).append("=")
- .append(percentEncode(paramMap.get(key)));
- }
- // 这里注意对canonicalizedQueryString进行编码
- stringToSign.append(percentEncode(canonicalizedQueryString.substring(0)));
- return stringToSign.toString();
- }
- private static String percentEncode(String value) throws UnsupportedEncodingException {
- return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*",
- "%2A").replace("%7E", "~") : null;
- }
- public static AjaxResult checkTimestamp(String requestId, String userTimestamp){
- if (StringUtils.isBlank(userTimestamp)) {
- log.debug("checkSignature, missing parameters, requestId {}, timestamp {}",
- requestId, userTimestamp);
- return AjaxResult.error(ReturnCode.REQUIRED_PARAM_MISSING);
- }
- LocalDateTime urlDateTime = DateUtils.parseDateTime(userTimestamp);
- if (null == urlDateTime) {
- log.debug("checkSignature, time format error, requestId {}, timestamp {}",
- requestId, userTimestamp);
- return AjaxResult.error(ReturnCode.DATETIME_FORMAT_ERROR);
- }
- LocalDateTime now = LocalDateTime.now();
- if (urlDateTime.isAfter(now.plusSeconds(SignatureUtil.MAX_TIME_DIFF))
- || urlDateTime.isBefore(now.minusSeconds(SignatureUtil.MAX_TIME_DIFF))) {
- log.debug("checkSignature, time is shift too many, in {}, now {}", urlDateTime, now);
- return AjaxResult.error(ReturnCode.DATETIME_SHIFT_TOO_MANY);
- }
- return AjaxResult.success();
- }
- public static AjaxResult checkSignature(String requestId, String strToSign,
- String userSignature, String aesKey) {
- if (StringUtils.isBlank(strToSign)) {
- return AjaxResult.success();
- }
- if (StringUtils.isBlank(userSignature)) {
- log.debug("checkSignature, missing parameters, requestId {}", requestId);
- return AjaxResult.error(ReturnCode.REQUIRED_PARAM_MISSING);
- }
- String signature = createSignature(strToSign, aesKey);
- if (StringUtils.isEmpty(signature)) {
- log.debug("checkSignature, calc signature null {}", requestId);
- return AjaxResult.error(SIGN_CHECK_FAIL);
- }
- boolean check = signature.equals(userSignature);
- if (!check) {
- log.debug(
- "checkSignature, signature not equal, strToSign {}, user signature {}, calc signature {}",
- strToSign, userSignature, signature);
- return AjaxResult.error(SIGN_CHECK_FAIL);
- }
- return AjaxResult.success();
- }
- private static String createSignature(String strToSign, String key) {
- try {
- SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(ENCODING),
- SignatureUtil.HMAC_SHA256);
- Mac mac = Mac.getInstance(SignatureUtil.HMAC_SHA256);
- mac.init(signingKey);
- byte[] rawHmac = mac.doFinal(strToSign.getBytes(ENCODING));
- log.debug("printHexBinary= {}", DatatypeConverter.printHexBinary(rawHmac));
- log.debug("printBase64Binary= {}", DatatypeConverter.printBase64Binary(rawHmac));
- return DatatypeConverter.printBase64Binary(rawHmac);
- } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException ignore) {
- }
- return null;
- }
- public static void main(String[] args) {
- createSignature(
- "code%3D12%26password%3DdB123456%26username%3D1088%26uuid%3Dacca0f11d8e2450e85fd45d76c49b951",
- "s#e@5f98H*^his%t");
- }
- }
|