HMAC Signature

Clients can make a request to most web services by sending an HMAC signature on the HTTP Authorization request header. A request header with an HMAC signature looks like the following:


Note: for readability the line breaks have been added between the key/value pairs, but the Authorization value should be sent as a string with no line breaks. The principal ID and principal ID namespace parameters are optional and not required by all web services.

Generating an HMAC Signature

A signature is generated by calculating a digest using the HMAC-SHA256 hashing algorithm. The inputs to the hashing algorithm include the WSKey secret and a normalized string that represents the current request.

To build the pre-hashed string concatenate the following elements separated by new line characters:

  1. The client’s WSKey
  2. A timestamp value calculated for the request in seconds.
  3. A nonce value generated for the request.
  4. The request entity-body hash if one was calculated and included in the request, otherwise, an empty string.
  5. The HTTP request method in upper case: HEAD, GET, POST, PUT, or DELETE
  6. The string literal
  7. The string literal 443
  8. The string literal /wskey
  9. The query component of the web service request URI normalized as described in Section of HTTP MAC authentication scheme

HMAC Signature Example

If making a GET request to the following URL

With the following parameters:

Key:  jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa
Secret:  UYnwZbmvf3fAXCEa0JryLQ==
Timestamp: 1361408273
Nonce: 981333313127278655903652665637

The pre-hashed string would look like the following:


Note that the line numbers are there to illustrate that there is a new line character at the end. Also note that when making requests to URLs that have no query parameters, there should only be a single newline at the end of this pre-hashed string.

After calculating the signature, it should be base64 encoded.

digest = HMAC-SHA256 ( wskey_secret, prehashed_string )
signature = base64 ( digest )

This request would generate the following Authorization header value. This example does not include body content. Even if it did, because the there is no key/value pair in the Authorization header for the entity-body hash, line 4 of the pre-hashed string is an empty string.

Example (space added for readability) 
timestamp="1361408273", nonce="981333313127278655903652665637", 

Requests that send a nonce or timestamp used on a previous request are considered invalid.