签名验证
BlockATM Webhook 使用 HMAC-SHA256 签名验证请求的真实性。
验证原理
HMAC-SHA256(secretKey, payload)请求头
BlockATM-Signature-V2
HMAC-SHA256 签名
BlockATM-Request-Time
请求时间戳(毫秒)
BlockATM-Event
事件类型
验证步骤
步骤 1:提取参数
从请求头中提取:
BlockATM-Signature-V2:签名BlockATM-Request-Time:时间戳请求体:payload
步骤 2:计算签名
使用相同的算法计算签名:
步骤 3:时间戳验证
验证请求是否在有效时间窗口内:
完整验证示例
安全建议
为什么必须验证签名?
Webhook 签名验证是保障您系统安全的关键环节。如果不验证签名,攻击者可以伪装成 BlockATM 向您的系统发送伪造的支付通知,可能导致:
虚假发货:基于伪造的"支付成功"通知向用户发货,但实际未收到款项
资金损失:基于伪造的"付币成功"通知确认交易,但实际区块链上并无此交易
业务混乱:伪造的订单状态更新可能导致您的业务逻辑出现异常
因此,必须始终验证签名,切勿跳过此安全检查。
1. 始终验证签名
警告:切勿跳过签名验证步骤。即使在开发测试环境中,也建议保持签名验证逻辑的正确实现。
验证流程:
从请求头提取
BlockATM-Signature-V2和BlockATM-Request-Time获取原始请求体(raw body),不要解析后再获取,因为 JSON 解析可能改变内容
拼接签名字符串:
原始payload + "&time=" + 时间戳使用相同的 HMAC-SHA256 算法计算签名
使用恒定时间比较(
hmac.compare_digest)防止时序攻击
常见错误:
2. 验证时间戳
时间戳验证用于防止重放攻击(Replay Attack)。攻击者可能截获合法的 Webhook 通知并重新发送,试图重复触发您的业务逻辑。
时间窗口建议:
推荐时间窗口:5 分钟(300000 毫秒)
如果 BlockATM 的服务器时间与您的服务器时间存在偏差,可以适当放宽,但不建议超过 15 分钟
验证逻辑:
3. 使用 HTTPS
强烈建议:生产环境中必须使用 HTTPS协议的 Webhook URL。使用 HTTP 明文传输可能导致请求被截获、篡改或重放。
证书要求:
推荐使用受信任 CA 颁发的 SSL/TLS 证书
避免使用自签名证书
定期检查证书有效期,及时续期
4. 幂等处理
同一 Webhook 事件可能会收到多次,原因是:
BlockATM 的重试机制(见下方说明)
您的服务器响应超时但实际处理成功
网络抖动导致的重复请求
实现幂等的建议:
BlockATM 重试机制:如果 Webhook 投递失败(您的服务器未返回 HTTP 200),BlockATM 会按以下策略重试:
第 1 次重试:1 分钟后
第 2 次重试:5 分钟后
第 3 次重试:30 分钟后
第 4 次重试:2 小时后
第 5 次重试:24 小时后
如果 5 次重试均失败,将停止投递。
5. 记录日志
完善的日志记录对于问题排查和安全审计至关重要。
建议记录的日志:
接收日志
收到请求的时间、事件类型、订单号
审计追踪
验证日志
签名验证结果、时间戳验证结果
问题排查
处理日志
业务处理开始/成功/失败
业务审计
错误日志
异常信息、堆栈跟踪
Bug 定位
日志示例:
6. 快速响应
重要:您的 Webhook 处理接口应该在接收到请求后立即返回 HTTP 200,然后再异步处理业务逻辑。这可以避免因处理耗时过长导致的请求超时和 BlockATM 重试。
推荐架构:
7. 错误处理
重要:如果您的 Webhook 处理失败(返回非 200 状态码),BlockATM 会认为投递失败并按照重试策略重新发送。
正确的错误处理:
提示:如果您的业务逻辑确实无法处理某个事件(如订单已撤销),可以返回 200 而不是错误码。这样 BlockATM 就不会重试,避免无限循环。
Last updated