如何配置钉钉机器人安全设置中的加签密钥避免请求被拦截

文章导读
配置钉钉机器人加签密钥的核心是使用 HMAC-SHA256 算法对时间戳和密钥进行签名,并将结果作为参数附加到 webhook 地址中。该方案适合服务端主动推送消息场景,风险边界在于时间戳格式错误或密钥复制不完整会导致请求被返回 401 状态码拦截。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

配置钉钉机器人加签密钥的核心是使用 HMAC-SHA256 算法对时间戳和密钥进行签名,并将结果作为参数附加到 webhook 地址中。该方案适合服务端主动推送消息场景,风险边界在于时间戳格式错误或密钥复制不完整会导致请求被返回 401 状态码拦截。

先说结论:开启加签后,必须在请求 URL 中携带正确计算的时间戳和签名参数,否则钉钉网关会直接拒绝请求。

  • 先判断:确认机器人安全设置已选择“加签”模式并复制完整密钥。
  • 优先做:使用 HMAC-SHA256 算法计算签名并对结果进行 URL 编码。
  • 再验证:发送测试请求确认 HTTP 状态码为 200 且机器人收到消息。

命令速用版

以下 Python 代码片段可直接用于生成签名参数,适用于大多数服务端语言逻辑参考。

import hmac
import hashlib
import base64
import urllib.parse
import time

secret = 'SECxxxxxxxxxx'  # 替换为机器人设置的密钥
timestamp = str(round(time.time() * 1000))
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

print(f"timestamp={timestamp}")
print(f"sign={sign}")

为什么会这样

钉钉网关通过校验签名和时间戳来确认请求来源的合法性和时效性。加签机制防止了 webhook 地址泄露后被第三方恶意调用发送垃圾消息,同时时间戳限制了请求的有效窗口,避免重放攻击。

如何配置钉钉机器人安全设置中的加签密钥避免请求被拦截

分步处理

按照以下顺序完成配置和代码修改,每一步完成后检查对应状态。

步骤 1:获取密钥
在钉钉机器人管理页面,安全设置栏选择“加签”,复制显示的密钥。密钥通常以 SEC 开头,复制时注意不要包含多余空格或换行。

步骤 2:生成时间戳
代码中获取当前时间毫秒级时间戳。必须使用毫秒值(13 位整数),不能使用秒值或字符串格式时间。

步骤 3:计算签名
将时间戳和密钥用换行符连接,使用 HMAC-SHA256 算法计算哈希值,再进行 Base64 编码和 URL 编码。顺序不可颠倒,编码方式必须一致。

如何配置钉钉机器人安全设置中的加签密钥避免请求被拦截

步骤 4:拼接 URL
将原始 webhook 地址后追加参数,格式为&timestamp=xxx&sign=xxx。注意第一个参数前用?,后续参数用&,如果原始 URL 已含参数则全部用&

步骤 5:发送请求
使用 HTTP POST 方法发送 JSON 数据。请求头 Content-Type 必须设置为application/json

怎么验证是否生效

发送请求后检查 HTTP 响应状态码。如果配置正确,钉钉接口返回状态码 200 且 body 中包含"errcode":0。如果返回 401 或 errcode 非 0,通常表示签名计算错误或时间戳偏差过大。同时在钉钉群内观察是否实际收到测试消息,避免接口返回成功但消息被群设置拦截。

如何配置钉钉机器人安全设置中的加签密钥避免请求被拦截

常见坑

  • 密钥复制错误:SEC 密钥前后容易混入不可见字符,建议在代码中打印密钥长度核对。
  • 时间戳单位错误:必须使用毫秒级时间戳,使用秒级会导致签名校验失败。
  • URL 编码遗漏:签名结果包含特殊字符,必须进行 URL 编码后再拼接到 URL 中。
  • 换行符差异:字符串拼接时时间戳和密钥之间必须是标准换行符\n,Windows 环境下注意不要变成\r\n

常见问题

请求返回 401 状态码怎么办

401 表示签名校验失败,重点检查时间戳是否为毫秒值、密钥是否完整复制、签名算法是否为 HMAC-SHA256。

密钥泄露后是否可以更换

可以在钉钉机器人设置页面重新生成密钥,更换后所有旧代码中的密钥需同步更新,否则旧请求会被拦截。

支持 HTTP GET 请求吗

钉钉自定义机器人 webhook 仅支持 HTTP POST 请求,使用 GET 方法会直接返回错误。

参考来源

  • 钉钉开放平台,自定义机器人接入,https://open.dingtalk.com/document/robots/custom-robot-access