Reputation: 6749
When using HMAC to authenticate an API call, often the message to be hashed includes a lot of stuff that doesn't seem to add anything. For example, here are the steps for a generating the signature for an API:
hmacsha1(HTTP VERB + URI + JSON_REQUEST_CONTENT + DATETIME, "secret")
Why not just go like:
hmacsha1(JSON_REQUEST_CONTENT, "secret")
This is assuming that JSON_REQUEST_CONTENT is a JSON string that contains all of the relevant request information.
It seems to me like adding the HTTP VERB and URI (or whatever extra non-content-specific info) is just adding to the length of the message, and I don't understand the benefit.
Thanks!
Upvotes: 0
Views: 731
Reputation: 1121
HMACs are generally used to prevent message tampering, but they are also used to prevent replay of messages.
If the HMAC only included the payload and a secret that would only prevent tampering, if I sent the same message again it would be valid. By garnishing the request with other details (datetime or a nonce especially) that should prevent replay as well as tampering.
To use the datetime as salt for the hash, you generally will need to send the datetime with the message in clear text (although it could be roughly inferred from the time the message was received or sent in the request headers external to the payload). If the datetime is too far from what the server believes the time to be, the message will fail (e.g. not within a minute). If when the server does the same hash on the data and it doesn't get the same result, it will also fail the message.
To use a nonce, the most practical way is for the service to say, next time you send me a request, use this nonce. The nonce doesn't need to be sent in clear text with the request. When the server processes a message successfully, it says, next time use this nonce and the previous one becomes invalid.
Datetime prevents replay by ensuring that a message was sent at a specific time, a nonce prevents replay by using a single use password.
Upvotes: 2