State of HTTP Signatures?

The “Guide for new ActivityPub implementers” (here) links to draft 8 of HTTP Signatures, but it seems there are newer versions now that might not be exactly compatible? How are AP implementations treating this situation?


The only major difference I am aware of is how the algorithm field was handled, and that change doesn’t realistically create incompatibilities. Just eliminates a security vulnerability. I know Mastodon is up to date with that change. I know contributors have been keeping update with the latest drafts.

The main thing I noticed was the introduction of (created) and (expires), and I had to disable sending those for certain other servers to accept my signatures

I also notice that the algorithm change indicates that it should be ‘Derived from metadata associated with “keyId”’. Do we have such metadata?

From what I’ve seen it looks like most implementations have hardcoded SHA256…

Mastodon for sure hardcodes SHA256.

The go-fed implementation I think is slightly more flexible and is hs2019/expires compliant. It’s just not widely used. :wink:

I’m not sure there’s currently a standard to convey what kind of key metadata is associated with a key id. I think most Mastodon profiles, for example, just list id, owner, and publicKeyPem properties from the security vocabulary. There’s lots more that could be adopted.

Looks like the security vocab defines a signatureAlgorithm field. Would setting that on the key to (or another option as defined in RFC6931) be a reasonable method to indicate this?

I’m looking at the latest version of the HTTP sigs spec, since it has indeed changed a bit since we first implemented it, and tbh there are stuff i’m not sure about:

  • the rules for (created) and (expired) do not permit accounting for clock skew (which is an acknowledged shortcoming of the spec), and while that’s probably fine for (expired), that is probably not the case for (created)
  • I am very confused with, which states that if the signature Algorithm starts with “rsa”, and “(created)” is in the covered content, then the implementation MUST produce an error. Yet the example covers “(created)” and uses rsa-sha256?
  • there’s also confusion between (expired) and (expires). Most places talk about (expires) but one refers to (expired)
  • in the signature parameters, sometimes the created parameter is written as such, sometimes as (created)
  • It looks like the example uses “rsa-256”, which doesn’t seem to exist. Either way that’s an issue
  • I assume that’s a typo since it’s pretty consistent otherwise
  • created is the signature parameter, but it’s (created) when used as a pseudo-header in the signed content
  • regarding clock skew, I’m sorry, I don’t know what nbf stands for
  • alright, either way, if we consider the example to be wrong, then Mastodon probably does not need to support created and expires, as those MUST not be accepted for creation of signatures with the only algorithm it supports for now (arguably, it could/should support more algorithms, though)
  • (created) is also occasionally used in examples as a signature parameter, but I assume that is an error as it does not make for a proper token
  • I don’t know what nbf is either (might be from the JWT spec?), the open PR just adds some text allowing implementations to account for skew.
  • All algorithms other than hs2019 are deprecated, so it is important to support that
  • I didn’t catch that the first time, but yeah I see it now. Probably should report issues for the examples
1 Like

Other then the (speculative?) increase in hash digest size from 256 to 512, I don’t understand the differences between the sha-256 and hs2019 algorithms. Is there a reason to upgrade? The new algorithm looks very complicated, and I would prefer to limit the complexity of the HTTP Signature implementation in Mastodon as much as is feasibly possible while still maintaining interop. Specification complexity is a leading cause of security bugs in similar applications, and one of my favorite parts of HTTP Signatures up until now has been the straightforwardness of the algorithm.

hs2019 isn’t really a signature algorithm, the entire algorithm field is basically deprecated since its existence is a security hole. Technically the spec requires that the algorithm is derived from the keyId, but the mechanics of that aren’t defined, so most implementations (including Mastodon) simply use rsa-sha256 anyway

Yeah, I read the spec around hs2019 a bit fast and made the assumption it was RSASSA-PSS with SHA512, but even that way, I couldn’t get the examples to verify (and their description is pretty inconsistent, some of the examples claim to use SHA256, others SHA512, for the same key that is supposed to use SHA512).

While I made some progress with it (, it probably doesn’t make much sense to do anything with that until we have a standard mechanism to derive that info (but I could default to rsa-sha256 in the meantime).

The aforementioned PR has been merged into Mastodon, so the development branch should support the hs2019 “algorithm”, assuming the actual underlying algorithms to be the same as rsa-sha256 (as no mechanism for defining/using such key metadata is implemented), but accepting (created) and (expires) as well as parsing them correctly.

It still uses rsa-sha256 for outgoing requests.

Hey, I’m one of the Editors of the HTTP Signatures specification… how can I help?

There are talks in the IETF to do breaking changes to the specification to “make it better”. It would be good to hear from implementers here on what is working for you and what isn’t working for you. The comment about hs2019 not being defined is helpful… the goal with that was to define things as cryptosuites… and ideally, we wanted to close a security hole where you could say one thing in the algorithm field and then use a different key that some implementations were just blindly feeding into a cryptolibrary (that’s a bad idea, please don’t do that – it allows attackers to specially craft keys that can cause some badly implemented crypto libraries to do terrible things like… skip checking the validity of digital signatures!).

In any case, let me know how I can help.

If you’re wondering how you could help… post something about how you’re using HTTP Signatures to the IETF HTTP WG. Don’t be shy, if we don’t get enough feedback from implementers, the work will be shut down w/o a final RFC being created. To post, just send an email to

Here’s an example of the sort of thing to write:

1 Like