跳到主要内容

WebHook 密钥验证和验证算法

WebHook 签名介绍

Gitee WebHook 支持通过密钥进行安全验证。

用户通过配置不公开的 WebHook 密钥,在请求时对请求内容签名,服务端在收到请求后以同样的密钥进行签名验证,以确认收到的请求完整且可信任。整个过程 WebHook 密钥只存在于 Gitee 和服务端,不在网络传输中暴露。

相比密码验证的方式,签名验证可以有效避免在网络传输过程中 WebHook 密码泄露带来的安全问题。

WebHook 签名生成算法(参考)

如果 WebHook 使用了签名方式,在请求目标时会在当次请求头中加入名为 X-Gitee-Token,值为生成的签名内容。其签名实现算法如下:

签名参数说明

参数说明
timestamp当前时间戳,单位是毫秒,与请求调用时间误差不能超过 1 小时,请求时需和密钥一并发送
secret签名密钥,机器人安全设置页面,加签一栏下面显示的 SEC 开头的字符串
  • Step1:把 timestamp+"\n"+ 密钥当做签名字符串,使用 HmacSHA256 算法计算签名。
  • Setp2:对上述得到的结果进行 Base64 encode。
  • Setp3:对上述得到的结果进行 urlEncode,得到最终的签名(需要使用 UTF-8 字符集)。

第二步,把 timestamp 和第一步得到的签名值拼接到 URL 中。

签名计算示例代码

签名计算代码示例(Java)

Long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
return URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8");

签名计算代码示例(Python)

#python 2.7
import time
import hmac
import hashlib
import base64
import urllib

timestamp = long(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = bytes(secret).encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = bytes(string_to_sign).encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)