当前位置:   article > 正文

HMAC API 接口签名 Message安全验证_java hmac接口认证

java hmac接口认证

什么是HMAC

HMAC 全称(Hash-based Message Authentication Code,即基于Hash的消息的认证码)。 - 基本过程为对某个消息,利用提前共享的对称密钥和Hash算法进行加密处理,得到HMAC值。 - 该HMAC值提供方可以证明自己拥有共享密钥的对称密钥,并且消息自身可以利用HMAC确保未经篡改。

为什么需要 API 接口签名?

 对外开放的 API 接口都会面临一些安全问题,例如伪装攻击、篡改攻击、重放攻击以及数据信息泄漏的风险。利用 API 接口签名能方便的防范这些安全问题和风险。在设计 API 接口签名时主要考虑以下几点:

保证请求数据正确
       当请求中的某一个字段的值变化时,原有的签名结果就会发生变化。所以,只要参数发生变化,签名就要发生变化,否则请求将会是一个无效的请求。

保证请求来源合法
       一般情况下,生成签名的算法都会成对出现一个 appKey 和一个 appSecret,根据 appKey 能识别出调用者身份;根据 appSecret 能识别出签名是否合法。

识别接口的时效性
       一般情况下,签名和参数中会包含时间戳,这样服务端就可以验证客户端请求是否在有效时间内,从而避免接口被长时间的重复调用。

API签名可以理解为就是对API的调用进行签名保护。是在进行API调用时,加了一个调用者及其调用行为的指纹信息,以帮助服务端更好的识别用户及其调用行为的合法性。其直接目的归纳为:

(1)明确调用者的身份(确认调用者是谁)

(2)明确调用者的调用行为(确认调用者想要做什么)

图·API签名解决两个问题

而明确调用者的身份和调用行为后,可基于调用者的身份做到包括但不限于以下几点:

A:拒绝非法用户身份者的调用请求

B:拒绝越权使用者的调用请求,保护隐私

C:控制访问者的调用频率,保护服务

D:记录调用者的访问记录,以便追溯

由此可见,API签名的真正目的是:通过明确调用者的身份,以便控制API的访问权限,从而保护数据的安全性

API 接口签名验签实现机制


签名验签流程图

1 客户端向服务端申请 appKey,appSecret ,服务端下发 appKey,appSecret。

2 客户端集成 SDK 产生 sign,将 appKey,请求参数,时间戳,sign发送到服务端,服务端根据请求参数使用 SDK 中的签名规则生成签名来验证sign的合法性,之后返回结果。
 

代码

  1. //签名
  2. public static Map<String, String> generateSign(String appKey, String appSecret, String url, String method) throws NoSuchAlgorithmException, InvalidKeyException {
  3. Map<String, String> headers = new HashMap<String, String>();
  4. SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT_STRING);
  5. df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
  6. String timestamp = df.format(new Date());
  7. StringBuilder stringToSign = new StringBuilder();
  8. stringToSign.append(method.toUpperCase()).append(url).append(timestamp);
  9. String signature = sign(appSecret, stringToSign.toString());
  10. headers.put("signature", signature);
  11. headers.put("appKey", appKey);
  12. headers.put("timestamp", timestamp);
  13. return headers;
  14. }
  15. //验证签名
  16. public static String validateSign(String appSecret, String url, String method, String timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
  17. StringBuilder stringToSign = new StringBuilder();
  18. stringToSign.append(method.toUpperCase()).append(url).append(timestamp);
  19. return sign(appSecret, stringToSign.toString());
  20. }
  21. //签名和验签公用方法
  22. private static String sign(String appSecret, String stringToSign)
  23. throws InvalidKeyException, NoSuchAlgorithmException {
  24. SecretKeySpec signingKey = new SecretKeySpec(appSecret.getBytes(CHARSET), "HmacSHA1");
  25. Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA1);
  26. mac.init(signingKey);
  27. byte[] data = mac.doFinal(stringToSign.getBytes(CHARSET));
  28. return Base64.getEncoder().encodeToString(data);
  29. }

拼接请求字符串

请求参数主要有:

参数名称

类型

示例值

Version

固定为:20191001

20191001

SecretId

密钥ID

SKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE

Timestamp

当前时间戳

1569490800

Nonce

随机正整数

3557156860265374221

SignatureMethod

签名方式

HmacSHA256或HmacSHA1

HashedRequestPayload

包体签名字符串

UodgxU3P77iThrEJtsiHi2kjYJmNA2jGEgYNnMD%2FX0s%3D

更多学习资料 请关注微信公众号

个人学习微信公众号

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/380170
推荐阅读
相关标签
  

闽ICP备14008679号