HMAC Authentication

The hash-based message authentication code (HMAC) Authentication method provides replay protection, time-to-live, and request integrity. Our implementation requires that you use the sha-256 and hmac-sha-256 hashing algorithms. Before you can implement this auth method, you must ensure that you have a shared key. If you were not given a shared key when you registered, please request one from Bluefin Support.

An HMAC authentication header must contain the following properties:

Property Description
username This property must be set to your partnerId.
nonce This property must be set to a nonce. A nonce is a unique random string. If a nonce is encountered more than once during a 15 minute period the API call is rejected. It is your responsibility to ensure that the nonce is unique.
timestamp A unix timestamp. Our service will reject API calls with a timestamp older than 15 minutes.
response The response property is a HMAC-SHA256 hash (in hexadecimal format) of a number of the API call's properties. See the guide Building the String-to-Hash for a detailed description of string that must be included in the hash. Once you have the StringToSign, generate the response like this: Hex( HMAC-SHA256( sharedKey, StringToHash ) );

Build an HMAC Authentication Header

  1. Generate a nonce:
1l5daa1ju1b7lmljc5p4nev0ve
  1. Generate a unix timestamp:
//In JavaScript/Node.js
Math.round(new Date().getTime()/1000)
//output 1489574949

//In Java
(int) (System.currentTimeMillis() / 1000L)
//output 1489574949
  1. Generate the content hash by SHA-256 hashing the request body:
'\n' represents a newline character and '\t' represents a tab character.

sha-256({ 
\n\t\"partnerId\":                     \"WATERFORD\",
\n  \t\"partnerKey\": \"ef1ad938150fb15a1384b883a104ce70\",
\n  \t\"devicePayload\": \"02C400C037001C0A8692;6011********3331=2212:***?*15=090210=2CB56EC5E025C2F3C2C67FCF2D0C4C39BB19E60EF31192675E5F1DB6A90070E3000000000000000000000000000000000000000035343154313132373038629949960E001D20004A029603\",
\n  \t\"clientId\": \"my_client\",
\n  \t\"reference\": \"723f57e1-e9c8-48cb-81d9-547ad2b76435s\"
\n})

//output 9db4a2e377abca97c72c5d8b449948d3fb22fa18f305c3730f227e4f6514d4ce
  1. Build the String-to-Hash:

When creating the String-to-Hash, it is important that you follow the format described exactly as outlined below, otherwise the request will be rejected. The String-to-Hash is composed of the following elements.

Element Description
HttpVerb Should be set to 'POST' for all API calls.
CanonicalizedResource Should be the HTTP Request URI, without protocol, port and domain parts; the following list outlines the appropriate value for each endpoint:
  • validate partner = /api/partner/validate
  • validate device = /api/v1/device/validate
  • process payload = /api/decrypt/parser
nonce Same value as set in the auth header nonce property.
timestamp Same value as set in the auth header timestamp property.
ContentHash A SHA-256 hash in hexadecimal format of the HTTP POST's body. Our service expects you to hash the whole body, including any leading and trailing whitespaces that you may have included. See step 3.
\n The Unicode code point U+000A, commonly called newline).

The String-to-Hash is composed of these elements gathered together in this exact format. Once you have the String-to-Hash, you pass it into the HMAC-SHA256 hashing algorithm to generate the HMAC authentication header's response property.

HttpVerb + " " + CanonicalizedResource +
				"\n" + nonce + "\n" + timestamp +
        "\n" + "\n" + ContentHash;

For our example the String-to-Hash is:

"POST /api/authdebug\n1l5daa1ju1b7lmljc5p4nev0ve\n1489574949\n\n9db4a2e377abca97c72c5d8b449948d3fb22fa18f305c3730f227e4f6514d4ce"
  1. HMAC-SHA256 hash the String-to-Hash with the secret key:
Hex( HMAC-SHA256( 'ef1ad938150fb15a1384b883a104ce70',
         "POST /api/authdebug\n1l5daa1ju1b7lmljc5p4nev0ve\n1489574949\n\n9db4a2e377abca97c72c5d8b449948d3fb22fa18f305c3730f227e4f6514d4ce" ) )

//output 7fd904ec88c5dc9217e178bc8e115b950c243197b5116e3e1fc43061eeb846ac
  1. Build the Digest authentication header:
Authorization: 
		Hmac username="WATERFORD",
  	nonce="1l5daa1ju1b7lmljc5p4nev0ve",
  	timestamp=1489574949,
  	response="7fd904ec88c5dc9217e178bc8e115b950c243197b5116e3e1fc43061eeb846ac"

Example

The following example is for demonstration purposes only. The WATERFORD user is not configured for HMAC authentication and the header's timestamp is out of date; if you try the cURL command, you will receive an authentication required error message.

curl 'https://secure-cert.decryptx.com/api/partner/validate' \
    -X POST \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'authorization: Hmac username="WATERFORD", nonce="1l5daa1ju1b7lmljc5p4nev0ve",  timestamp=1489574949, response="7fd904ec88c5dc9217e178bc8e115b950c243197b5116e3e1fc43061eeb846ac"' \
    -d '{
            "reference"  : "723f57e1-e9c8-48cb-81d9-547ad2b76435"
        }'