Comment by resonious
A bit of a tangent. This isn't a dig on HMAC itself, but using HTTP request body or query string as the HMAC "message" is the worst. My employer provides some APIs with that sort of scheme and it's a very common source of technical customer support tickets.
The problem is that many people are using web frameworks that automatically turn body and query into some kind of hash map data structure. So when you tell them "use the request body as the HMAC message", they go "OK, message = JSON.stringify(request.body)", and then it's up to fate whether or not their runtime produces the same exact same JSON as yours. Adding a "YOU MUST USE THE RAW REQUEST BODY" to the docs doesn't seem to work. We've even had customers outright refuse to do so after we ask them to do so in the "why are my verifications failing" ticket. And good luck if it's a large/enterprise customer. Get ready to have 2 different serialization routines: one for the general populous, and one for the very large customer that wrote their integration years ago and you only now found out that their runtime preserves "&" inside JSON strings but yours escapes it.
Rant over...
> "&" inside JSON strings but yours escapes it
What escaping of "&" inside JSON are you talking about? Some unholy mix of JSON and urlencode?