前言
Http接口传输有很多加密方式, 如 AES
对称加密, RSA
非对称加密, 参数验签等, 下文主要简单示例参数如何验签。
原理
将 GET
参数和 appkey
通过如 MD5
之类的算法生成一个唯一不可逆的参数 sign
, 参数传递的同时传递签名参数 sign
。HTTP接收参数后根据自己持有的 appkey
和 appsecret
再次计算, 比对是否和传递的 sign
相同。
注意:appKey并不在http中传输,是计算摘要的密码盐
简单实现
maven依赖
1 2 3 4 5
| <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.12</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| ** * @author 当我遇上你 * @公众号 当我遇上你 * @since 2020-05-27 * * 参数验签 * * 现没有统一的签名机制,无需按业务区分。采用唯一的appKey和appSecret */ public class SignUtils {
private static final Logger logger = LoggerFactory.getLogger(SignUtils.class);
public static final String appKey = "idea360"; public static final String appSecret = "123456";
public static String getSignData(Map<String, String> params) { StringBuilder content = new StringBuilder(); List<String> keys = new ArrayList<>(params.keySet()); Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); if ("sign".equals(key)) { continue; } String value = params.get(key); if (value != null) { content.append(i == 0 ? "" : "&").append(key).append("=").append(value); } else { content.append(i == 0 ? "" : "&").append(key).append("="); } }
return content.toString(); }
public static String sign(Map<String, String> params) {
String outSignData = getSignData(params); logger.info("outSignData:{}", outSignData);
byte[] hmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, appSecret).hmac(outSignData); String sign = new String(Base64.encodeBase64(hmac)); logger.info("sign:{}", sign); return sign; }
public static boolean checkSignature(Map<String, String> params) { String inTimeStamp = params.getOrDefault("_t", "0"); LocalDateTime inTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(inTimeStamp)), ZoneOffset.ofHours(8)); Duration duration = Duration.between(inTime, LocalDateTime.now()); long seconds = duration.get(SECONDS); System.out.println("seconds: " + seconds); if (seconds > 3 * 60) { System.out.println("请求超时"); return Boolean.FALSE; }
String inSignData = getSignData(params); logger.info("inSignData:{}", inSignData);
byte[] inHmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, appSecret).hmac(inSignData); String sign2 = new String(Base64.encodeBase64(inHmac)); logger.info("sign2:{}", sign2);
String sign1 = params.getOrDefault("sign", ""); return sign1.equals(sign2); }
public static void main(String[] args) { Map<String, String> params = new HashMap<>(); params.put("appKey", appKey);
params.put("c", "v1"); params.put("u", "v2"); params.put("_t", String.valueOf(System.currentTimeMillis())); params.put("state", null); params.put("sessionId", "123");
String sign1 = sign(params); params.put("sign", sign1);
boolean checkSignature = checkSignature(params); System.out.println(checkSignature);
}
}
|
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。