凭证与唯一认证头
协议标识为 g24-hmac-sha256-v2。通过双方约定的安全渠道获取 audience、SSP ID、key ID 和 secret。secret 必须是标准、带 padding、可规范回编码的 Base64,解码后恰好 32 字节。HMAC 使用解码后的原始字节,不能直接把 Base64 文本当作密钥。
| 请求头 | 格式 |
|---|---|
X-G24-Key-Id |
1–64 个 ASCII 字母、数字或 ._- |
X-G24-Timestamp |
Unix 毫秒的十进制字符串,最多 16 位,不含前导零(单独 0 除外) |
X-G24-Nonce |
16 字节随机值编码为 32 个小写十六进制字符 |
X-G24-Signature |
完整 HMAC-SHA256,编码为 64 个小写十六进制字符 |
四个头各出现恰好一次。不接受重复头、逗号合并、多值数组或首尾空白,不自动 trim。audience 为双方配置的一致值,1–64 个安全 ASCII 字符;不从 Host 或转发头推断。SSP ID 最多 128 字节,字符规则同 key ID。
八字段签名原文
按下列顺序连接 UTF-8 字段,字段之间只放一个 LF(\n),末尾没有 LF。不能用 CRLF,也不能添加空行。
g24-hmac-sha256-v2
audience
ssp_id
POST
request_path
key_id
timestamp_ms
nonce
request_path 必须是实际请求的 origin-form 路径,例如 /openrtb/ssp-a。不包含域名、scheme、query 或 fragment;不重新编码路径。服务路径限制为最多 512 字节且身份必须符合 SSP 接入 的规范。
signature = lowercase_hex(HMAC_SHA256(base64_decode(secret), canonical_utf8))
算法包含协议标识本身,共八个字段。请求正文、scheme、Host、Content-Length 和响应均不在签名中。示例脚本不接收正文,也不执行网络请求。
时间窗与 Nonce
服务端接受 [effective_now - 30000, effective_now + 5000] 毫秒范围内的时间戳,两个端点均包含,即最多过去 30 秒、未来 5 秒。这里使用服务端有效时钟;客户端应同步时钟,不要靠预生成签名长期缓存请求。
每次发送尝试使用全新的随机 Nonce。去重键包含 SSP ID 和 Nonce,不包含 key ID;同一 SSP 切换密钥也不能重复使用仍有效的 Nonce。验签成功后即可能登记 Nonce,即使后续正文校验失败也不要重用它。过期但尚未清理的记录可能仍保守拒绝。
防重放仅保证同一进程内的登记唯一性;不保证跨节点或进程重启后去重。时间异常或认证资源不足会失败关闭,可能返回 503,不能绕过认证继续发送。
密钥轮换
当前 key 与最多一把 previous key 可在约定的重叠窗口内使用。previous key 的绝对截止时刻为毫秒时间戳,服务端有效时间达到或超过该时刻即拒绝;重载不会延长截止时间。双方应确认新 key 已可用、切换发送端,并在截止前停止旧 key。公开示例不能验证生产密钥是否已生效。
不要将 secret、完整认证头或带用户数据的正文放进日志、工单、截图、Git 或网页。示例通过环境变量读取真实输入,不接受把 secret 写成命令行参数。环境变量本身也不是秘密管理系统,需要受控运行环境。
安全边界与验算
元数据 HMAC 不证明正文来源、完整性或机密性。在明文链路上,截获者可能保留合法签名、修改未签正文并抢先提交;同进程去重只会拒绝后到的重复请求。双方应根据风险独立确定 TLS 或受信网络要求。
下载 签名脚本 和 公开固定向量。向量密钥是公开的 32 字节 0x11,仅供本地验算,不是可用凭证。运行方法见 示例,错误处理见 响应与排错。
协议与实现校核日期:2026-09-21。