1

I'm needing to verify an HTTP HMAC signature for a program I use (Drone CI, trying to create an extension), but nothing I'm trying is getting the results to match.

Specifically, the HTTP request looks like this:

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"}

I've tried messing around with sha256sum, hmac256, and openssl, swapping the values of Digest and signature, but none of them are making anything match.


Update:

I've tried the following code, but it still doesn't seem to be working:

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

Update 2:

The HMAC examples on Wikipedia are working just fine for me. Is there something I might be messing up from the HTTP request?

If it's worth anything, the request signing is apparently based on draft-cavage-http-signatures-10.


Update 3:

I've attempted to create the signature with the following format, still no dice though:

{"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

Assuming the above text is stored under the variable ${hmac_data}, the following was used to attempt (but failed) to reach the value of signature:

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

Update 4:

After a crud ton of messing around, Kiskae's answer got me to a solution.

In addition to what he said, I found that Drone base64 encodes the binary version of the string, rather than the ASCII one.

So, the new version of the above command (when using with Drone CI) would be the following:

${MESSAGE} is equal to the following:

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

And the command:

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

1 Answers1

0

They appear to be using an implementation of the http signatures draft.

The linked document explains the way the signature needs to be calculated and how to verify it. But this is probably why your example doesn't work:

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.

Basically the signature doesn't include just the message, probably to prevent replay attacks. Since you just hash the message it is working as intended.

Kiskae
  • 24,655
  • 2
  • 77
  • 74
  • Weird, just mentioned that as you posted that. Do you if it has to be in any particular order? (i.e. string - headers, or headers - string) – Hunter Wittenborn Jun 11 '21 at 01:59
  • Yes, since order of bytes changes the hash result any change in order will completely change the result. Section `2.3` of the document describes how you should construct the string that needs to be hashed. – Kiskae Jun 11 '21 at 02:03
  • Would you know if I'm still doing something wrong? I've been at it for about two hours, but everything's yet to match. (What I'm currently doing is posted under "Update 3".) – Hunter Wittenborn Jun 11 '21 at 04:27
  • It appears that the message body isnt a part of the signature, only the listed headers (or the default headers) are hashed. Security of the message body can be guarenteed by including a `Digest` header, including the digest header in the signature and verifying the digest separately. – Kiskae Jun 11 '21 at 18:52
  • I think I figured out the issue - Drone is encoding the signature in base64 from the **binary** version of the string. I was base64 encoding from the ASCII string, which I'm assuming was causing the issues. – Hunter Wittenborn Jun 11 '21 at 21:32