如何验证 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"}
我试过摆弄 sha256sum
、hmac256
和 openssl
,交换 Digest
和 signature
的值,但是 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.
基本上签名不仅仅包括消息,可能是为了防止重放攻击。由于您只是对消息进行哈希处理,因此它按预期工作。
我需要为我使用的程序(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"}
我试过摆弄 sha256sum
、hmac256
和 openssl
,交换 Digest
和 signature
的值,但是 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.
基本上签名不仅仅包括消息,可能是为了防止重放攻击。由于您只是对消息进行哈希处理,因此它按预期工作。