GH GambleHub

请求的签名和核实

请求签名证明发送者的真实性和内容的完整性。与TLS(保护通道)不同,应用程序签名使每个消息都可以验证并抵抗代理,缓存和延迟交付。

目标是:

1.真实(发送者)和完整性(未更改)。

2.不重复性(反弹保护)。

3.脱离传输(在HTTP,队列,webhook之上运行)。

4.可审计性(几个月后可复制)。

1)威胁模型(最低)

沿途的身体/头部替换。
Replay(合法请求的重播)。
标题标题的Downgrade/strip。
窃取集成的秘密。
非同步时钟(clock skew)和长队列。

2)选择原语

HMAC(对称性):简单快捷,密钥存储在双方。适用于B2B webhook和内部API。
RSA/ECDSA(不对称性):收件人私有密钥,收件人公开密钥。适用于开放式集成以及不共享秘密的重要性。
mTLS:在传输层进行相互身份验证;通常与NMAS/身体签名结合使用。
JWT/JWS:适用于啤酒代币和自给自足的烙印;对于主体签名,最好使用+JWS Detached/HTTP消息签名。
HTTP Message Signatures(查询选定部分的签名):REST的现代方法。

建议:对于webhooks-HMAC+timestamp+nonce+身体规范化;对于公共API-HTTP消息信号或JWS;高风险-添加mTLS。

3)规范化(我们确切的签名)

签名需要确定性字符串,双方都可以平等地恢复。

参考阵容:

method \n path_with_query_normalized \n content-type \n digest: SHA-256=BASE64(SHA256(body)) \n x-ts: <unix    iso> \n x-nonce: <uuid> \n host \n x-tenant: <tenant_id> \n
最后一行:

canonical = join("\n", fields)
signature = HMAC(secret, canonical)  # или ECDSA_sign(private_key, canonical)
规则:
  • 规范化查询参数的路径和顺序。
  • 空格/unicode/寄存器-捕获(例如,下箱头,trim)。
  • 大身体-散列(文章)而不包括"原样"。

4)标题格式

HMAC的示例:

X-Signature-Alg: hmac-sha256
X-Signature: v1=hex(hmac),ts=1730379005,nonce=550e8400-e29b-41d4-a716-446655440000,kid=prov_42
Digest: SHA-256=BASE64(SHA256(body))
X-Tenant: brand_eu
不对称示例(ECDSA P-256):

Signature: keyId="prov_42", alg="ecdsa-p256-sha256",
ts="2025-10-31T12:30:05Z", nonce="550e...", headers="(request-target) host digest x-tenant",
sig="BASE64(raw_signature)"

其中"kid"/"keyId"允许从注册表中选择密钥(请参阅轮换)。

5)接受方验证

伪代码:
python def verify(request):
1) Basic assert abs (now () - request. ts) <= ALLOWED_SKEW  # напр., 300 с assert not replayed(request. nonce, window = TTL) # store nonce/ts in KV

2) Restore canonical canonical = build_canonical (
method=request. method,
path=normalize_path(request. path, request. query),
content_type=request. headers["content-type"],
digest=hash_body(request. body),
ts=request. ts,
nonce=request. nonce,
host=request. headers["host"],
tenant=request. headers. get("x-tenant")
)

3) Get the key key = key_registry. get(request. kid) # secret (HMAC) или public key (ECDSA)

4) Verify if request signature. alg. startswith("hmac"):
ok = hmac_compare(key. secret, canonical, request. signature)
else:
ok = asym_verify(key. public, canonical, request. signature)

5) Solution if not ok: return 401, "SIGNATURE_INVALID"
return 200, "OK"

恒定时间比较HMAC,在快速KV(TTL event_id交付窗口)中存储"nonce"/"( ts,≥)"。

6)反倒带和窗户

Timestamp+Nonce:拒绝此窗口中"± Δ"(例如5分钟)和nonce重播的请求。
对于webhook:使用稳定的"event_id"和inbox表比nonce更可靠。
重新交付(retrai)必须使用相同的ts/nonce/event_id而不是生成新的。

7)多特南特和地区

保存per tenant/region: 'kid=<tenant>键:<region> <key_id>。
共享秘密池和限制;遵守数据驻留。
在标题/规范化中,指定"X-Tenant"和区域是可验证上下文的一部分。

8)密钥管理和轮换

密钥注册表(KMS/Vault):"kid",类型,算法,状态("active","deprecating","retired"),"valid_from/valid_to"。
双秘密:同时保持当前密钥和下一个密钥(接收器同时接受两者)。
按时间表和事件轮换(损害)。
按键(如果可能)并限制对密钥材料的访问。
密钥访问和操作日志。

9)与mTLS和OAuth结合

mTLS在证书级别检查通道和"您是谁"。
签名可保护消息(通过代理/keshi/队列有用)。
OAuth/JWT补充了身份验证/授权,但本身并不能保证身体的完整性(除非在规范化中签名)。
最佳实践:mTLS+身体签名(文摘)+HMAC/ECDSA+简短的'ts' interval。

10)错误和响应代码

'401 SIGNATURE_INVALID'是错误的签名/算法。
'401 KEY_REVOKED'-'kid'无效/过期。
'400 TIMESTAMP_OUT_OF_RANGE'-时钟/窗口。
'409 NONCE_REPLAYED'-检测到重复。
'400 DIGEST_MISMATCH'-身体发生了变化。
'415 UNSUPPORTED_ALGORITHM'是未解决的'alg'。
'429 TOO_MANY_ATTEMPTS' 是按键/tenant进行转弯。

在机器可读的"error_code"中踢出确切的原因;不要像现在这样返回秘密/规范化。

11)可观察性和审计

度量标准:
  • `verify_p95_ms`, `verify_error_rate`, `digest_mismatch_rate`, `replay_blocked_rate`, `alg_usage{hmac,ecdsa}`, `clock_skew_ms`.
  • Logi(结构):"kid","alg","tenant","region","ts","nonce","digest_hash","decision","reason"。
  • Tracing:"签名"属性。kid`, `signature.alg`, `signature.ts_skew`.
  • 审计:不变轮换日志、密钥使用和公差标志。

12)生产力

通过流媒体哈希身体(不要保持内存)。
通过"kid"缓存公共密钥,并在事件中使用短TTL和残疾。
在edge/gateway上进行预检查(ts/nonce/格式)。
HMAC比ECDSA快;ECDSA更适合于外部集成和"不可分离"密钥。

13)测试

Fixtur集:相同的查询→相同的规范化/签名;"肮脏"的空白/查询/标题顺序→可持续。
Negative:不正确的"kid/alg",修改后的身体/主机,重播nonce,过时的ts,clock skew。
基于属性的:任何等效的查询都会产生一个canonical字符串。
Interop:跨语言检查(Go/Java/Node/Python)。
混乱:延迟,撤退,"即时"更改密钥。

14)花花公子(runbooks)

1."SIGNATURE_INVALID"爆发'

检查密钥轮换、时钟旋转、发送者对规范化的更改。
暂时为旧的"孩子"启用"双接受",通知合作伙伴。

2."REPLAYED"的成长'

增加TTL存储,在发件人处检查转发器,检查时钟.

在边缘阻止滥用IP/ASN。

3. "DIGEST_MISMATCH"大量

检查代理/压缩/标头覆盖;记录规范化版本。
禁用破坏身体/标题的中介。

4.对钥匙的损害

立即恢复"kid",翻译为"next_kid",重新生成所有秘密/令牌,访问审核。

15)典型错误

在不固定顺序的情况下签署"身体部分"或JSON →字段排列的漏洞。
缺乏"文摘"→代理可以谨慎地改变身体。
没有无声的长窗口"ts" →通过下拉打开。
在没有KMS/Vault的环境变量中存储秘密。
比较签名不是稳定时间。
忽略规范化→转发攻击中的"主机"/"路径"。
混合不同的Tenant和地区的"kid"。

16)售前支票清单

  • 定义了规范化格式(方法,path +query, content-type, Digest, ts, nonce, host, tenant)。
  • 由HMAC/ECDSA使用"kid",密钥注册表和双秘密实现。
  • 包括Webhook的反放电(nonce+ts)和inbox/event_id存储。
  • 设置了错误代码/retrais策略和trottling per tenant/key。
  • 可观察性:verify,logi,traces,alerta on flock的度量。
  • 钥匙旋转是自动的;审计和访问权受到限制。
  • 规范化和跨语言兼容性测试套件。
  • 集成商文档,带有3-4种语言和fixtures的示例。
  • mTLS包含在敏感集成中;JWT仅用作补充,不是身体签名的替代品。

结论

请求的签名和验证不是"单个标题",而是纪律:清晰的规范化,短的时间窗口,反反反射,按键旋转和可观察性。为所有集成(API和webhook)构建单一标准,使用"kid"/KMS,在旋转时接受两个密钥,并且您的轮廓将具有抗欺骗性、可预测性和易于审核性。

Contact

联系我们

如需任何咨询或支持,请随时联系我们。我们随时准备提供帮助!

Telegram
@Gamble_GC
开始集成

Email — 必填。Telegram 或 WhatsApp — 可选

您的姓名 可选
Email 可选
主题 可选
消息内容 可选
Telegram 可选
@
如果填写 Telegram,我们也会在 Telegram 回复您。
WhatsApp 可选
格式:+国家代码 + 号码(例如:+86XXXXXXXXX)。

点击按钮即表示您同意数据处理。