前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AK/SK 认证模式在开放 API 中的应用

AK/SK 认证模式在开放 API 中的应用

作者头像
程序猿杜小头
发布2023-09-02 10:59:14
1.2K0
发布2023-09-02 10:59:14
举报
文章被收录于专栏:程序猿杜小头程序猿杜小头

为了验证开放 API 请求的合法性,必须要对 API 请求方进行认证,一般有两种认证模式,即HTTP BasicAK/SK

在 HTTP Basic 认证模式中,API 请求方在调用开放 API 时需要在请求头中传递 用户名/密码 的 BASE64 编码值,BASE64 编码是可逆的,这定然存在密码泄露的风险。

而 AK/SK 认证模式则可以避免明文传输密码,这种认证模式广泛应用于保障云服务商开放 API 的安全性。在 AK/SK 认证模式中,API 请求方需要使用由 API 提供商分配的Access KeySecret Key进行认证。其中,Access Key 是公开的密钥,用于标识 API 请求方的身份;Secret Key 则是私有的密钥,只有 API 请求方和 API 提供商持有

在 API 调用过程中,API 请求方需要使用HMAC算法对签名消息体进行签名,然后将生成的签名和 Access Key 一并传递给 API 提供商;API 提供商根据 Access Key 拿到请求方的 Secret Key,然后使用相同的 HMAC 算法对同一签名消息体进行签名,接着与请求方发送的签名进行比对,从而判断该请求是否合法。

HMAC

MAC (Message Authentication Code) 是一种基于共享密钥的消息认证技术,其被广泛应用于消息真实性和完整性的验证场景。而 HMAC (Hash-based Message Authentication Code) 是一种特殊类型的 MAC,它使用诸如 MD5、SHA-1 和 SHA-256 等哈希函数来计算消息摘要 (HMAC 与 MAC 的差异并不仅仅局限于此)。

签名如何生成

代码语言:javascript
复制
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec("Secret Key".getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
Base64.getEncoder().encodeToString(mac.doFinal("签名消息体"));

签名消息体如何生成

签名消息体的生成策略参考 OceanBase[1]

代码语言:javascript
复制
Http Method + "\n" + Content MD5 + "\n" + Content-Type + "\n" + Date + "\n" + Host + "\n" + URI + Query Parameter
  • Http Method

HTTP 请求方法,大写英文。包括:GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS 和 TRACE。

  • Content MD5

HTTP 请求体 的 MD5 值,转为十六进制大写英文字母。即使 Content MD5 内容为空,连接符 “\n” 是依然存在的。

代码语言:javascript
复制
byte[] bodyByte = "{\"name\":\"test01\",\"description\":\"test\",\"regionId\":1}".getBytes(StandardCharsets.UTF_8);
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(bodyByte);
String hex = new BigInteger(1, digest.digest()).toString(16).toUpperCase();
String contentMd5 = StringUtils.leftPad(hex, 32, "0");
  • Date

请求发起时间,其遵循 RFC1123 格式。

代码语言:javascript
复制
String rfc1123Date = ZonedDateTime.now(ZoneId.of("GMT")).format(DateTimeFormatter.RFC_1123_DATE_TIME);
  • URI

请求的路径,不包括域名与查询参数部分。URI 与 Query Parameter 拼接是通过 “+” 而非 “\n”。

  • Query Parameter

查询参数。以 “?” 开头,按 key 升序排序,以 “=” 连接键值,以 “&” 分隔键值对。key、value 需进行 URL 编码,编码规则遵照 RFC3986 规定。此外,查询参数是需要排序的。注意:对于a=1&a=2&a=3这种,需转为a=1,2,3值升序排列且逗号分隔。

代码语言:javascript
复制
// Map<String, List<String>> paramMap
String urlParam = paramMap.entrySet().stream()
        .sorted(Map.Entry.comparingByKey())
        .map(e -> {
            String value = e.getValue().stream()
                    .filter(StringUtils::isNotEmpty).sorted().collect(Collectors.joining(","));
            return String.format("%s=%s", encoder(e.getKey()), encoder(value));
        })
        .collect(Collectors.joining("&"));

总结

本文部分代码摘自《OceanBase 云平台开放 API 文档》。最后提一嘴:AK/SK 认证模式或者说 HMAC 自身是不具备防御重放攻击 (replay attack) 能力的,规避重放攻击可以借助timestampnoncesequence number方案[2]

参考资料

[1]

OceanBase AK/SK 签名生成规则: https://www.oceanbase.com

[2]

重放攻击与 HMAC: https://www.linkedin.com/advice/0/how-do-you-prevent-replay-attacks-when-using-hmac-authentication

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿杜小头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HMAC
  • 签名如何生成
  • 签名消息体如何生成
  • 总结
    • 参考资料
    相关产品与服务
    API 网关
    腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档