如何验证 Bash 中的 HTTP HMAC 签名?

How can I verify an HTTP HMAC Signature in Bash?

我需要为我使用的程序(Drone CI,尝试创建扩展)验证 HTTP HMAC 签名,但我没有尝试让结果匹配。

具体来说,HTTP 请求如下所示:

POST / HTTP/1.1
Host: 127.0.0.1
User-Agent: Go-http-client/1.1
Content-Length: 50
Accept: application/vnd.drone.validate.v1+json
Accept-Encoding: identity
Content-Type: application/json
Date: Wed, 09 Jun 2021 01:25:07 GMT
Digest: SHA-256=digest
Signature: keyId="hmac-key",algorithm="hmac-sha256",signature="signature",headers="accept accept-encoding content-type date digest"

{"data":"data"}

我试过摆弄 sha256sumhmac256openssl,交换 Digestsignature 的值,但是 none 他们中的任何人都匹配。


更新:

我已经尝试了以下代码,但它似乎仍然无法正常工作:

MESSAGE='{"data":"data"}'
SECRET="secret" # This isn't any value in the request, is it?

echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "${SECRET}" | base64 -w 0

更新 2:

HMAC examples on Wikipedia 对我来说工作得很好。 HTTP 请求有什么问题吗?

如果值得的话,请求签名显然是基于 draft-cavage-http-signatures-10


更新 3:

我已尝试使用以下格式创建签名,但仍然没有成功:

{"data":"data"}
accept: application/vnd.drone.validate.v1+json
accept-encoding: identity
content-type: application/json
date: Wed, 09 Jun 2021 01:25:07 GMT
digest: SHA-256=digest

假设上述文本存储在变量 ${hmac_data} 下,以下内容用于尝试(但失败)达到 signature 的值:

echo -n "${hmac_data}" | openssl dgst -sha256 -hmac "${key}" | awk '{print }' | base64 -w 0

更新 4:

经过大量的折腾, 找到了解决方案。

除了他说的,我发现Drone base64编码字符串的binary版本,而不是ASCII one.

因此,上述命令的新版本(与 Drone CI 一起使用时)如下:

${MESSAGE} 等于:

accept: application/vnd.drone.validate.v1+json
accept-encoding: identity
content-type: application/json
date: Wed, 09 Jun 2021 01:25:07 GMT
digest: SHA-256=digest

和命令:

echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "${SECRET}" -binary | base64 -w 0

他们似乎在使用 http signatures draft.

的实现

链接文档解释了需要计算签名的方式以及如何验证它。但这可能就是您的示例不起作用的原因:

2.1.3. headers

OPTIONAL. The headers parameter is used to specify the list of HTTP headers included when generating the signature for the message.

基本上签名不仅仅包括消息,可能是为了防止重放攻击。由于您只是对消息进行哈希处理,因此它按预期工作。