签名验证

BlockATM Webhook 使用 HMAC-SHA256 签名验证请求的真实性。

验证原理

HMAC-SHA256(secretKey, payload)

请求头

Header
说明

BlockATM-Signature-V2

HMAC-SHA256 签名

BlockATM-Request-Time

请求时间戳(毫秒)

BlockATM-Event

事件类型

验证步骤

步骤 1:提取参数

从请求头中提取:

  • BlockATM-Signature-V2:签名

  • BlockATM-Request-Time:时间戳

  • 请求体:payload

步骤 2:计算签名

使用相同的算法计算签名:

步骤 3:时间戳验证

验证请求是否在有效时间窗口内:

完整验证示例

安全建议

circle-exclamation

为什么必须验证签名?

1. 始终验证签名

triangle-exclamation

验证流程

  1. 从请求头提取 BlockATM-Signature-V2BlockATM-Request-Time

  2. 获取原始请求体(raw body),不要解析后再获取,因为 JSON 解析可能改变内容

  3. 拼接签名字符串:原始payload + "&time=" + 时间戳

  4. 使用相同的 HMAC-SHA256 算法计算签名

  5. 使用恒定时间比较(hmac.compare_digest)防止时序攻击

常见错误

2. 验证时间戳

时间戳验证用于防止重放攻击(Replay Attack)。攻击者可能截获合法的 Webhook 通知并重新发送,试图重复触发您的业务逻辑。

时间窗口建议

  • 推荐时间窗口:5 分钟(300000 毫秒)

  • 如果 BlockATM 的服务器时间与您的服务器时间存在偏差,可以适当放宽,但不建议超过 15 分钟

验证逻辑

3. 使用 HTTPS

triangle-exclamation

证书要求

  • 推荐使用受信任 CA 颁发的 SSL/TLS 证书

  • 避免使用自签名证书

  • 定期检查证书有效期,及时续期

4. 幂等处理

同一 Webhook 事件可能会收到多次,原因是:

  • BlockATM 的重试机制(见下方说明)

  • 您的服务器响应超时但实际处理成功

  • 网络抖动导致的重复请求

实现幂等的建议

circle-info

BlockATM 重试机制:如果 Webhook 投递失败(您的服务器未返回 HTTP 200),BlockATM 会按以下策略重试:

  • 第 1 次重试:1 分钟后

  • 第 2 次重试:5 分钟后

  • 第 3 次重试:30 分钟后

  • 第 4 次重试:2 小时后

  • 第 5 次重试:24 小时后

如果 5 次重试均失败,将停止投递。

5. 记录日志

完善的日志记录对于问题排查和安全审计至关重要。

建议记录的日志

日志类型
记录内容
目的

接收日志

收到请求的时间、事件类型、订单号

审计追踪

验证日志

签名验证结果、时间戳验证结果

问题排查

处理日志

业务处理开始/成功/失败

业务审计

错误日志

异常信息、堆栈跟踪

Bug 定位

日志示例

6. 快速响应

circle-info

重要:您的 Webhook 处理接口应该在接收到请求后立即返回 HTTP 200,然后再异步处理业务逻辑。这可以避免因处理耗时过长导致的请求超时和 BlockATM 重试。

推荐架构

7. 错误处理

triangle-exclamation

正确的错误处理

circle-info

提示:如果您的业务逻辑确实无法处理某个事件(如订单已撤销),可以返回 200 而不是错误码。这样 BlockATM 就不会重试,避免无限循环。

Last updated