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.
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:
Response content type (accept header)\n
ISO-8601 UTC timestamp\n
: In lower case. Example: `post`
: 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
Response content type
: 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");`
: The public key of the user. In lower case. Example: `0c6b33651708eb09c8a8d6036b79d739`
A complete message representation might look like this:
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))
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);
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=