HTTP签名算法
更新时间:2026-04-23
1. 功能概述
为保障事件总线在通过 HTTP/HTTPS 渠道投递事件时的数据安全性与可信性,平台支持基于 HMAC-SHA256 的签名鉴权机制。
当用户在 HTTP 投递目标(Target)中配置 Secret Key(SK)并开启签名校验后,百度云在发送请求时会自动对消息进行签名;接收方可基于相同规则进行签名校验,从而实现:
- 请求来源可信(防伪造)
- 请求内容未被篡改(防篡改)
- 请求具备时效性(防重放)
2. 核心流程
2.1 配置阶段(用户侧)
- 用户在 “云监控BCM->事件总线->创建事件规则” 创建 HTTP/HTTPS 目标
- 勾选高级配置里的 “开启签名校验”
-
配置 Secret Key(填写 32 位随机字符串,可随机生成,相同http地址需填写相同的SK信息)
Secret Key 仅在平台与接收方之间共享,请妥善保管

2.2 配置存储
- Secret Key 以
params形式存储在 Target 元数据中 - 在每次事件投递时,用于签名计算
- 平台不会在请求中明文传输 Secret Key
2.3 发送阶段(百度云侧)
每次发送 HTTP 请求时,系统执行如下步骤:
- 获取当前 UTC 时间戳
- 构造待签名字符串:
Go
1StringToSign = <Timestamp> + "\n" + <RawBody>
- 使用 Secret Key 进行 HMAC-SHA256 计算
- 将签名结果与时间戳写入 HTTP Header 并发送请求
2.4 接收阶段(开发者侧)
接收方需要按照以下流程完成校验:
- 从 Header 获取签名与时间戳
- 校验时间戳合法性(防重放)
- 使用相同算法重新计算签名
- 比对签名结果
3. 参数约定
| Header Key | 说明 | 示例 |
|---|---|---|
| X-Bce-Signature | 计算得出的签名值 | f75c...d8a2 |
| X-Bce-Timestamp | 发送时的 Unix 时间戳(秒级) | 1709601950 |
4. 签名算法说明
- 算法:HMAC-SHA256
- 编码:Hex(十六进制字符串)
签名公式:
Go
1Signature = HexEncode(
2 HMAC-SHA256(
3 SecretKey,
4 Timestamp + "\n" + Body
5 )
6)
5. 示例代码
5.1 发送方(签名生成)
Go
1package auth
2
3import (
4 "crypto/hmac"
5 "crypto/sha256"
6 "encoding/hex"
7 "fmt"
8)
9
10// GenerateSignature 生成 HMAC-SHA256 签名
11func GenerateSignature(secret, timestamp, body string) string {
12 stringToSign := fmt.Sprintf("%s\n%s", timestamp, body)
13
14 h := hmac.New(sha256.New, []byte(secret))
15 h.Write([]byte(stringToSign))
16
17 return hex.EncodeToString(h.Sum(nil))
18}
5.2 接收方(签名校验)
Go
1package main
2
3import (
4 "bytes"
5 "crypto/subtle"
6 "io"
7 "net/http"
8 "strconv"
9 "time"
10)
11
12const (
13 SecretKey = "your-configured-secret-key"
14 MaxTimeDiff = 300 // 5分钟
15 HeaderSignature = "X-Bce-Signature"
16 HeaderTimestamp = "X-Bce-Timestamp"
17)
18
19func VerifyHandler(w http.ResponseWriter, r *http.Request) {
20 receivedSign := r.Header.Get(HeaderSignature)
21 receivedTimestamp := r.Header.Get(HeaderTimestamp)
22
23 if receivedSign == "" || receivedTimestamp == "" {
24 http.Error(w, "Missing Auth Headers", http.StatusUnauthorized)
25 return
26 }
27
28 // 时间戳校验
29 ts, err := strconv.ParseInt(receivedTimestamp, 10, 64)
30 if err != nil {
31 http.Error(w, "Invalid Timestamp", http.StatusBadRequest)
32 return
33 }
34
35 now := time.Now().Unix()
36 if now-ts > MaxTimeDiff || ts-now > MaxTimeDiff {
37 http.Error(w, "Request Timed Out", http.StatusRequestTimeout)
38 return
39 }
40
41 // 读取 Body
42 bodyBytes, _ := io.ReadAll(r.Body)
43 r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
44 bodyStr := string(bodyBytes)
45
46 // 回算签名
47 expectedSign := GenerateSignature(SecretKey, receivedTimestamp, bodyStr)
48
49 // 安全比较(防时序攻击)
50 if subtle.ConstantTimeCompare([]byte(expectedSign), []byte(receivedSign)) != 1 {
51 http.Error(w, "Invalid Signature", http.StatusUnauthorized)
52 return
53 }
54
55 w.WriteHeader(http.StatusOK)
56}
6. 安全性说明
6.1 防重放攻击
通过 X-Bce-Timestamp 控制请求有效时间窗口(默认建议 5 分钟) 超出时间窗口的请求将被拒绝
6.2 防篡改
签名覆盖完整 Body 任意字段修改都会导致签名不一致
6.3 防伪造
Secret Key 仅存在于: 百度云服务端 用户接收服务端 第三方无法生成合法签名
6.4 算法选择
HMAC-SHA256 安全性高(抗碰撞、抗伪造) 性能开销低(适用于高频调用场景)
评价此篇文章
