HMAC authentication

The SmartStore.Net Web API uses the HMAC authentication method to protect data from unauthorized access.

HMAC (hash-based message authentication code) is a sessionless authentication method, where the integrity of a resource request is guaranteed through a this request representing code (called message representation) and a cryptological hash function. The procedure is considered to be very safe. It is used for example by Amazon to protect their S3 Web services.

SmartStore.Net uses SHA-256 as hash function, which is why this authentication procedure is often called HMAC-SHA256.

The consumer must transmit a timestamp with each request which may not differ too far from the server time, otherwise the authentication will fail. The storekeeper can configure this time window in the plugin configuration. The default value is 15 minutes. To prevent replay attacks the timestamp must be younger than the one of a previous request.

Message representation

The message representation is a concatenation of various informations separated by newline characters. All values are required but can be empty (in case of Content-MD5). It must be build as follows:


    HTTP method\n
    Content-MD5\n
    Response content type (accept header)\n
    Canonicalized URI\n
    ISO-8601 UTC timestamp\n
    Public key


HTTP method: In lower case. Example: `post`

Content-MD5: The base64 encoded MD5 hash of the HTTP body, so `base64(md5Hash(content))`. For GET requests this fied is empty. The value should be equal to the optional Content-MD5 request header field. For example the MD5 hash for the content

    {"OrderId":152,"Note":"Hello world!","DisplayToCustomer":false,"CreatedOnUtc":"2013-11-09T11:15:00"}

is `lgifXydL3FhffpTIilkwOw==`.

Response content type: The value of the accept header field. In lower case. Example: `application/json, text/javascript, /`

Canonicalized URI: The complete URI of the requested resource (including query string). In lower case. Example: `http://localhost:1260/odata/v1/ordernotes`

ISO-8601 UTC timestamp: Current UTC date and time including milliseconds. Must be equal to the request header field SmartStore-Net-Api-Date. Example: `2013-11-09T11:37:21.1918793Z`. The API accepts milliseconds with 7 and 3 digits. Can be created in C# as follows: `string timestamp = DateTime.UtcNow.ToString("o");`

Public key: The public key of the user. In lower case. Example: `0c6b33651708eb09c8a8d6036b79d739`

A complete message representation might look like this:


    post
    lgifXydL3FhffpTIilkwOw==
    application/json, text/javascript, */*
    http://localhost:1260/odata/v1/ordernotes
    2013-11-09T11:42:48.4715986Z
    0c6b33651708eb09c8a8d6036b79d739 

HMAC signature

The signature is the computed hash of the message representation by using SHA-256 and the user's secret key. Always UTF8 encode the secret key and the message representation while calculating the hash. Example of creating the HMAC signature:


    public string CreateSignature(string secretKey, string messageRepresentation)
    {
    	if (string.IsNullOrWhiteSpace(secretKey) || string.IsNullOrWhiteSpace(messageRepresentation))
    		return "";
    
    	string signature;
    	var secretBytes = Encoding.UTF8.GetBytes(secretKey);
    	var valueBytes = Encoding.UTF8.GetBytes(messageRepresentation);
    
    	using (var hmac = new HMACSHA256(secretBytes))
    	{
    		var hash = hmac.ComputeHash(valueBytes);
    		signature = Convert.ToBase64String(hash);
    	}
    	return signature;
    }


The signature is transmitted as a base64 encoded string together with the schema using authorization header field.
For above message representation and the secret key `3025c89ebaab20b71e0e42744239bf50` the authorization header field is

    Authorization: SmNetHmac1 +yvONYvJmQl19omu1uE3HVlQ7afd7Qqkk8DrNrfUbe8=



Last edited Jul 14, 2014 at 3:18 PM by mgesing, version 3