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:

Authorization: http://www.worldcat.org/wskey/v2/hmac/v1
clientId="tsFsoBXToV1uR8GEMJCcxz9NYpVvutsA5cJAD9cnKUc4FGYEntM6UkcIVlYp4ZhYFteVLAxOWJDUV85W",
timestamp="1361306811",
nonce="762343395744465450467911322335",
signature="2DwPAIYqlCOH9xCHM7PSnOBoVKk/PHrHPeIGmmEK/AI=",
principalID="8eaa9f92-3951-431c-975a-d7dfkd9rd131",
principalIDNS="urn:oclc:wms:da"



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 www.oclc.org
  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 3.3.1.1 of HTTP MAC authentication scheme


HMAC Signature Example

If making a GET request to the following URL

https://circ.sd00.worldcat.org/pulllist/128156?inst=128807

With the following parameters:

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

The pre-hashed string would look like the following:

jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa
1361408273
981333313127278655903652665637
    
GET
www.oclc.org
443
/wskey
inst=128807
    

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)

http://www.worldcat.org/wskey/v2/hmac/v1 
clientId="jdfRzYZbLc8HZXFByyyLGrUqTOOmkJOAPi4tAN0E7xI3hgE2xDgwJ7YPtkwM6W3ol5yz0d0JHgE1G2Wa", 
timestamp="1361408273", nonce="981333313127278655903652665637", 
signature="5O6SRig58wqm6gqEu3oSODVte6Albon9CCvNrZHCoys="




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