Files
sign-doc/docs/README.md
SF-bytebytebrew 87cf193268 🎉 init
2025-05-21 12:52:16 +08:00

99 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API签名机制
## 1. 概述
API签名机制是一种安全措施用于验证API请求的合法性和完整性同时防止请求被篡改或重放。本文档描述了我们的API签名机制的工作原理、实现方式以及集成指南。
## 2. 签名机制原理
### 2.1 基本流程
1. 客户端获取API密钥AccessKeyId和对应的密钥SecretKey
2. 客户端按照规则构造请求参数,包含必要的认证信息
3. 客户端使用SecretKey对请求参数进行签名计算
4. 客户端将签名和请求参数一起发送到服务器
5. 服务器验证签名,通过验证后处理请求
### 2.2 安全特性
- **身份认证**确保API调用者是合法授权的用户
- **数据完整性**:防止请求被篡改
- **防重放攻击**通过时间戳和随机数nonce机制防止请求被重放
- **密钥保护**SecretKey不在请求中直接传输
## 3. 签名参数说明
### 3.1 基本参数
| 参数名 | 类型 | 必填 | 说明 |
|-------|------|-----|------|
| AccessKeyId | String | 是 | 访问密钥ID |
| channelId | String | 是 | 合作渠道方ID标识调用方身份 |
| timestamp | Long | 是 | 请求时间戳(毫秒) |
| nonce | String | 是 | 随机字符串,用于防重放攻击 |
| signature | String | 是 | 请求签名 |
### 3.2 签名算法
支持的签名算法:
- MD5默认最快
- SHA1
- SHA256
- HMAC-SHA256最安全
## 4. 签名计算方法
1. 收集所有请求参数URL参数、表单参数**不包括signature参数**
2. 按参数名称字典序升序排序
3. 构造规范化的请求字符串:`key1=value1&key2=value2&...`URL编码非字母数字字符
4. 在请求字符串末尾添加密钥:`key1=value1&key2=value2&...&key=YOUR_SECRET_KEY`
5. 使用指定算法计算签名:`signature = HASH_ALGORITHM(规范化请求字符串)`
6. 将签名以十六进制形式添加到请求参数
## 5. 安全注意事项
- SecretKey必须妥善保管不可泄露
- 服务端验证时间戳拒绝处理超过5分钟的请求
- 服务端记录并验证nonce拒绝处理重复的nonce防重放
- 采用HTTPS传输增强安全性
- channelId与AccessKeyId必须匹配防止身份冒用
## 6. 集成说明
我们提供了多种语言的API签名工具实现存放在各自对应的目录中
- `/go` - Go语言实现
- `/rust` - Rust语言实现
- `/java` - Java语言实现
- `/kotlin` - Kotlin语言实现
- `/python` - Python语言实现
- `/typescript` - TypeScript语言实现
- `/csharp` - C#语言实现
每种语言实现都包含完整的签名计算和验证功能,以及详细的使用示例。开发者可以根据项目需求选择合适的语言实现,并参考示例进行集成。
## 7. 快速测试
每个语言实现目录中都包含可以直接运行的测试程序,方便开发者测试签名机制。测试程序默认使用根目录下的`.env`文件中的配置参数,您可以根据需要修改这些参数。
```
# .env文件示例
ACCESS_KEY_ID=your-access-key-id
SECRET_KEY=your-secret-key
CHANNEL_ID=your-channel-id
API_BASE_URL=https://api.example.com/v1
```
## 8. 常见问题
### 8.1 签名验证失败的常见原因
- 时间戳超出允许范围(服务器时间与客户端时间差异过大)
- 使用了已过期或已使用过的nonce
- 参数排序不正确
- URL编码处理不正确
- 签名算法不匹配
- 密钥错误
- channelId与AccessKeyId不匹配