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

com.xiongyingqi.common.utils.sign.SignUtils Maven / Gradle / Ivy

The newest version!
package com.xiongyingqi.common.utils.sign;


import com.xiongyingqi.common.utils.Assert;
import com.xiongyingqi.common.utils.CollectionUtils;
import com.xiongyingqi.common.utils.string.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * Sign utils.
 *
 * @author xiongyingqi
 * @version 2016-08-21 00:25
 */
public abstract class SignUtils {
  public static final String DEFAULT_CHARSET = "UTF-8";
  private static final Logger logger = LoggerFactory.getLogger(SignUtils.class);

  /**
   * Check sign if sign result matches presents string. Default ignore empty value.
   *
   * @param signed       presents signed string.
   * @param params       to sign params.
   * @param unsignedKeys keys that not join sign.
   * @return True if sign matches. Other wise false.
   */
  public static boolean checkSign(String signed, Map params, Set unsignedKeys, String
      append) {
    return checkSign(signed, params, unsignedKeys, append, DEFAULT_CHARSET);
  }

  /**
   * Check sign if sign result matches presents string. Default ignore empty value.
   *
   * @param signed       presents signed string.
   * @param params       to sign params.
   * @param unsignedKeys keys that not join sign.
   * @param charset      charset.
   * @return True if sign matches. Other wise false.
   */
  public static boolean checkSign(String signed, Map params, Set unsignedKeys, String
      append, String
                                      charset) {
    return checkSign(signed, params, unsignedKeys, append, charset, true);
  }

  /**
   * Check sign if sign result matches presents string.
   *
   * @param signed           presents signed string.
   * @param params           to sign params.
   * @param unsignedKeys     keys that not join sign.
   * @param charset          Charset.
   * @param ignoreEmptyValue ignore pair when value is empty.
   * @return True if sign matches. Other wise false.
   */
  public static boolean checkSign(String signed, Map params, Set unsignedKeys, String append,
                                  String charset, boolean ignoreEmptyValue) {
    if (signed == null) {
      return false;
    }
    String sign = sign(params, unsignedKeys, append, charset, ignoreEmptyValue);
    boolean match = sign.equalsIgnoreCase(signed);
    if (!match) {
      logger.info("Mismatch sign! signed: {} ours: {}", signed, sign);
    } else if (logger.isDebugEnabled()) {
      logger.debug("Check sign succeed! signed: {} ours: {}", signed, sign);

    }
    return match;
  }

  /**
   * Sign the params to md5 message.
   *
   * @param params           to signed parameters.
   * @param unsignedKeys     keys that not join the sign params.
   * @param append
   * @param charset          charset of md5.
   * @param ignoreEmptyValue empty value should'nt join sign.   @return md5(upper case)
   */
  public static String sign(Map params, Set unsignedKeys, String append, String
      charset, boolean ignoreEmptyValue) {
    Assert.notEmpty(params, "parameters is null!");

    SortedMap sortedMap = convertToSignMap(params, unsignedKeys, ignoreEmptyValue);
    String signString = toSignString(sortedMap);
    if (StringUtils.hasText(append)) {
      signString += append;
    }
    if (logger.isDebugEnabled()) {
      logger.debug("Final sign string: {}", signString);
    }
    return md5(signString, charset);
  }

  public static SortedMap convertToSignMap(Map params, Set
      unsignedKeys, boolean ignoreEmptyValue) {
    Assert.notEmpty(params, "parameters is null!");

    SortedMap sortedMap = new TreeMap();
    sortedMap.putAll(params);
    if (ignoreEmptyValue) {
      for (Iterator> iterator = sortedMap.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry entry = iterator.next();
        if (!StringUtils.hasText(entry.getValue())) {
          iterator.remove();
        }
      }
    }
    if (CollectionUtils.isEmpty(unsignedKeys)) {
      return sortedMap;
    }
    for (String unsignedKey : unsignedKeys) {
      String removed = sortedMap.remove(unsignedKey);
      logger.debug("Removed unsigned key: '{}' with value: {}", unsignedKey, removed);
    }
    return sortedMap;
  }

  public static String toSignString(SortedMap params) {
    Assert.notEmpty(params, "parameters is null!");
    StringBuilder builder = new StringBuilder();
    Iterator> iterator = params.entrySet().iterator();
    for (; iterator.hasNext(); ) {
      Map.Entry entry = iterator.next();
      // ignore empty string
      if (!StringUtils.hasText(entry.getKey())) {
        continue;
      }
      builder.append(entry.getKey())
          .append("=")
          .append(entry.getValue());
      if (iterator.hasNext()) {
        builder.append("&");
      }
    }
    String signMessage = builder.toString();
    if (logger.isDebugEnabled()) {
      logger.debug("Returning sign string: \"{}\" by params: {}", signMessage, params);
    }
    return signMessage;
  }

  public static String md5(String signString, String charset) {
    Assert.hasText(signString, "Origin sign is null!");
    try {
      byte[] bytes = signString.getBytes(charset);
      String md5 = DigestUtils.md5DigestAsHex(bytes).toUpperCase();
      if (logger.isDebugEnabled()) {
        logger.debug("Returning md5: {} by sign string: {}", md5, signString);
      }
      return md5;
    } catch (UnsupportedEncodingException e) {
      logger.error("", e);
    }
    return null;
  }
}