api参数签名生成sign
前言
api对外接口,考虑到安全性,以及接口受到恶意攻击。都会做参数签名。
参数签名逻辑
参数字典升序,后面拼接上密钥,转换成大写,采用MD5不可逆加密,生成sign,参数校验同理生成新的sign与原有的sign进行对比。
注意:密钥不可传递
package com.fb.xujimanage.util; import com.alibaba.fastjson.JSONObject; import org.apache.commons.codec.digest.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; /**@author summer.chou * 参数签名类,为了安全密钥不能传递 */ public class Md5SignUtils { private static final Logger logger = LoggerFactory.getLogger(Md5SignUtils.class); /*** * 字典升序(加密参数排序) * @param json 请求加密参数 * @return 排序的字符串 */ public static String generatString(JSONObject json) { if (json.isEmpty()) { return ""; } Set<String> keySet = json.keySet(); ArrayList<String> list = new ArrayList<>(keySet); StringBuffer sb = new StringBuffer(); Collections.sort(list, String.CASE_INSENSITIVE_ORDER); for (String key : list) { String value = json.getString(key); if (value != null) { if (!"sign".equals(key)) { sb.append(key + "=" + value + "&"); } } } return sb.toString().substring(0, sb.length() - 1); } /*** * 加密 * @param secret 密钥 * @param json 请求参数 * @return 签名字符串 */ public static String Md5Sign(String secret, JSONObject json) { String s = generatString(json); logger.info("排序后的字符串-->"+s); String preSign = s + "&appSecret=" + secret; return DigestUtils.md5Hex(preSign).toUpperCase(); } /** * 验证签名, 仅支持MD5. * * @param json 请求去参数(不用排序) * @param key 商户秘钥 * @param sign 签名字符串 * @return 验签结果 */ public static boolean checkSign(JSONObject json, String key, String sign) { if (key == null) { throw new RuntimeException("key不能为空"); } if (sign == null) { throw new RuntimeException("需要验签的字符sign为空"); } return sign.equals(Md5Sign(key,json)); } /** * 时间戳精确到截取后四位 * @param date * @return */ public static Long getSecondTimestamp(Date date){ if (null == date) { return Long.valueOf(0); } String timestamp = String.valueOf(date.getTime()); int length = timestamp.length(); if (length > 5) { return Long.valueOf(timestamp.substring(0,length-5)); } else { return Long.valueOf(0); } } }
使用方式
@RunWith(SpringRunner.class) @SpringBootTest(classes = XujimanageApplication.class) public class TestApplication { //密钥 @Value("${org.api.key}") private String app_key; @Test public void checkSign(){ JSONObject json=new JSONObject(); json.put("startTime","qqqqqqqqqqqq"); String sign=Md5SignUtils.Md5Sign(app_key,json); //参数校验 boolean bool=Md5SignUtils.checkSign(json,app_key,sign); System.out.println("=================>"+bool); } }