深入理解飞书 Webhook 签名验证机制与实现
问题背景
在对接飞书开放平台的事件订阅功能时,常会遇到签名验证失败的问题。尽管应用创建、事件订阅配置及 Webhook 地址填写均正确,代码部署上线后,飞书后台点击'验证'按钮时仍可能报错:
warn: Mud.Feishu.Webhook.FeishuEventValidator[0] 请求头签名验证失败:计算 +OGVt6ye......, 期望 bc5b503a......
日志显示数据解密成功且事件类型识别正确,但签名验证失败。这表明 Encrypt Key(加密密钥) 是正确的,但签名验证逻辑存在问题。
飞书 Webhook 的安全机制
两把钥匙的故事
飞书为每个应用配置了两把'钥匙':
| 钥匙类型 | 用途 | 格式示例 |
|---|---|---|
| Verification Token (验证令牌) | URL 验证请求 | fCt8xobpOKdb4yA0UoKJrhNTUaXTzJnf |
| Encrypt Key (加密密钥) | 数据加密/解密、签名验证 | go4kwHmzAbCdEfGhIjKlMnOpQrStUvWx |
简单来说:
- Verification Token 类似门牌号,用于确认请求来源。
- Encrypt Key 类似钥匙,用于开门和解密,同时也用于签名验证。
飞书发送请求的完整流程
- 准备事件数据。
- 使用 Encrypt Key 加密数据。
- 生成签名。
- 发送 HTTP 请求(包含
X-Lark-Signature,X-Lark-Request-Timestamp,X-Lark-Request-Nonce等头部)。
服务器端处理流程
收到飞书请求后,需按以下顺序验证和处理:
- 验证签名:若失败则拒绝请求。
- 解密数据:若失败则拒绝请求。
- 处理事件:业务逻辑处理。
- 返回响应:返回成功状态。
常见实现错误
坑 #1:用错了签名算法
错误实现: 误以为飞书使用 HMAC-SHA256。
// 错误:使用了 HMAC
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(encryptKey));
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(signString));
var signature = Convert.ToBase64String(hashBytes);


