API 签名设计详解
签名的作用与目的
API 签名的核心目标是 验证请求的完整性和真实性,防止数据被篡改或伪造,通过签名机制,服务器可以确认请求确实由合法客户端发起,且内容未被中途修改。
关键功能:
- 防篡改:确保传输参数未被非法修改。
- 身份验证:验证请求发送者的身份(如 API Key + Secret)。
- 防重放攻击:结合时间戳或随机数,防止请求被重复利用。
签名算法选择
算法类型 | 典型实现 | 特点 |
---|---|---|
对称加密(HMAC) | HMAC-SHA256 | 性能高,适合高频请求;依赖共享密钥 |
非对称加密(RSA) | RSA + SHA256 | 安全性更高,但计算耗时;适合低频高安全场景 |
哈希摘要(MD5/SHA1) | MD5, SHA1 | 不推荐(MD5 已被破解,SHA1 逐渐淘汰) |
推荐方案:
- HMAC-SHA256:主流选择,平衡安全性与性能。
- RSA:金融级 API 或敏感场景。
签名参数设计
参与签名的参数
参数类型 | 说明 | 示例 |
---|---|---|
固定参数 | 必填参数(如 API Key、时间戳) | api_key=xxx , timestamp=12345678 |
业务参数 | 接口具体参数(如订单号、金额) | order_id=1001 , amount=100 |
随机参数 | 防止重放攻击(如随机数或时间戳) | nonce=abc123 |
参数标准化规则
- 排序规则:按参数名字母升序排列(避免顺序差异导致签名不一致)。
- 空值处理:过滤空值参数(如
null
或空字符串)。 - 编码规则:统一使用 URL 编码(如空格转为
%20
)。
示例:
原始参数:
{ "api_key": "test_key", "timestamp": 1633000000, "order_id": "1001", "amount": 100, "nonce": "abc123" }
标准化后:
api_key=test_key&amount=100&order_id=1001&nonce=abc123×tamp=1633000000
签名生成流程
拼接待签字符串
将标准化后的参数按 key=value
格式拼接,并用 &
连接。
添加秘钥(Secret)
- HMAC 方案:将秘钥直接作为 HMAC 的密钥。
- RSA 方案:用私钥对字符串签名。
生成签名
- HMAC-SHA256:
import hmac, hashlib secret = "your_secret_key" message = "api_key=test_key&amount=100&order_id=1001&nonce=abc123×tamp=1633000000" signature = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
- RSA:
from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding private_key = load_private_key() # 加载私钥 signature = private_key.sign( message.encode(), padding.PKCS1v15(), hashes.SHA256() )
传输签名
将签名作为请求头或参数发送(如 signature=xxx
)。
签名验证流程
服务器端验证步骤
- 提取客户端传的签名和参数。
- 按相同规则标准化参数并拼接字符串。
- 使用相同的算法和秘钥生成服务器端签名。
- 对比客户端签名与服务器签名是否一致。
失败处理
- 签名不一致 → 返回
401 Unauthorized
。 - 时间戳过期 → 返回
400 Bad Request
(需结合时间戳校验)。
安全最佳实践
措施 | 说明 |
---|---|
使用 HTTPS | 防止中间人攻击,确保传输过程加密。 |
限制秘钥权限 | 仅用于签名,避免用于其他业务逻辑。 |
定期轮换秘钥 | 降低秘钥泄露风险(如每月更换一次)。 |
时间戳容差设置 | 允许客户端时间与服务器偏差(如 ±5 分钟)。 |
防止重放攻击 | 结合时间戳或随机数(nonce),并设置有效时间窗口。 |
相关问题与解答
问题 1:为什么 API 签名需要时间戳?
解答:
时间戳用于 防止重放攻击,即使攻击者截获了合法请求,也无法在过期后重复发送。
- 服务器校验
timestamp
是否在允许的时间窗口内(如当前时间 ±5 分钟)。 - 结合
nonce
(随机数)可进一步确保每个请求唯一。
问题 2:如何选择哈希算法?
解答:
根据 安全性 和 性能 权衡:
- 高安全性场景(如金融 API):选择
HMAC-SHA256
或RSA-SHA256
。 - 低性能设备(如物联网终端):优先
HMAC-SHA256
,避免 RSA 的计算开销。 - 弃用算法:避免使用 MD5、SHA
到此,以上就是小编对于“api 签名设计”的问题就介绍到这了,希望介绍的几点解答对大家有用,有任何问题和不懂的,欢迎各位朋友在评论区讨论,给我留言。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复