clientKey + accessSecret + timestamp => signature 是一种基于 HMAC(Hash-based Message Authentication Code) 的 API 鉴权机制,广泛用于云服务和开放平台中,属于 AK/SK(Access Key / Secret Key)鉴权模型 的典型实现。其核心思想是:客户端使用共享密钥(accessSecret)对请求关键信息(如 clientKey、timestamp 等)进行签名,服务端用相同密钥验证签名,从而确认请求来源合法、未被篡改,并防止重放攻击。
一、鉴权原理说明
该方式通常包含以下要素:
clientKey(AK):明文传输,用于标识调用者身份(如 AppKey、AccessKey)。
accessSecret(SK):保密的密钥,仅客户端和服务端知晓,不通过网络传输。
timestamp:Unix 时间戳,用于防止重放攻击(通常限制时间窗口,如 ±15 分钟)。
signature:使用 HMAC 算法(如 HMAC-SHA256)对特定字符串(由 clientKey、timestamp 等组成)和 accessSecret 加密生成。
客户端签名流程:
构造待签名字符串(canonical string),通常包括:
HTTP 方法
请求路径与查询参数
关键 Header(如
Date、Content-Type)clientKey 和 timestamp
对该字符串使用 HMAC-SHA256 算法,以 accessSecret 为密钥进行加密。
将结果进行 Base64 或 Hex 编码,得到
signature。将
clientKey、timestamp、signature等放入请求头(如Authorization或自定义 Header)。
服务端验证流程:
从请求中提取
clientKey,查出对应的accessSecret。按相同规则重建待签名字符串。
用
accessSecret对该字符串计算 HMAC,生成服务端签名。比较客户端
signature与服务端签名是否一致。同时校验
timestamp是否在有效时间窗口内,防止重放。
此机制确保了:
身份认证(只有持有 SK 者能生成有效签名)
数据完整性(任何篡改都会导致签名失效)
防重放(依赖 timestamp 或 nonce)
二、具体示例
参考 中的实现方式:
假设:
clientKey = "myAppKey123"accessSecret = "mySecret456"timestamp = 1700000000(Unix 时间戳)nonce = "a1b2c3d4"(随机字符串,增强唯一性)
步骤 1:构造待签名字符串
将 timestamp、nonce、clientKey 按 ASCII 升序排序后拼接:
sorted = ["1700000000", "a1b2c3d4", "myAppKey123"]
joined = "1700000000a1b2c3d4myAppKey123"步骤 2:计算 HMAC-SHA256 签名
import hmac
import hashlib
secret = "mySecret456"
message = "1700000000a1b2c3d4myAppKey123"
signature = hmac.new(
key=secret.encode('utf-8'),
msg=message.encode('utf-8'),
digestmod=hashlib.sha256
).hexdigest()
# 假设计算结果为:'dfe8b9a1c3e4f5...'步骤 3:构造请求头
GET /api/data HTTP/1.1
Host: api.example.com
Authorization:
clientKey="myAppKey123",
timestamp="1700000000",
nonce="a1b2c3d4",
signature="dfe8b9a1c3e4f5..."服务端验证:
查到
myAppKey123对应的accessSecret = "mySecret456"用相同逻辑拼接字符串并计算 HMAC
比对签名,同时检查
timestamp是否在允许范围内(如当前时间 ±900 秒)
若一致且时间有效,则鉴权通过。
该模式是阿里云、腾讯云等主流云厂商 API 鉴权的基础,也见于 Higress 网关插件 和国内 CDN 资源保护方案 。
评论区