Why HMAC is a Good Idea

September 29, 2014

Blog | Development | Why HMAC is a Good Idea
Why HMAC is a Good Idea

When validating the integrity of messages sent between systems, it’s common to rely on Message Authentication Codes. These codes are a hashed value created using some or all the values within the message being transmitted and sent along with the message itself. On the receiving end, the same set of values are used to re-create the code. If the code received in the transmission matches the code that was generated by the server, then this guarantees1 that the data received has not been altered in any way during transmission. 

That’s a mouthful. Let’s look at a brief example:

Given the following data2:

HMAC 1 - http://www.geekhive.com

Using the MD5 hashing algorithm, available online here, the hash value for this message is:


c41470db4429b39a78a925e1210df864


Therefore, the payload sent to the server will be: 

HMAC 2 - http://www.geekhive.com

When the server receives this payload and generates an MD5 hash value of the Message, the same HMAC value should be calculated.

Even a minor change to the message, such as the capitalization of a single letter, will significantly alter the HMAC value. For instance:

HMAC 3 - http://www.geekhive.com 

Therefore, our server can say with high confidence that the message has not been altered after its creation by the sender application.

There is a potential risk that the payload could be re-sent multiple times to the server, as the payload does not contain any time-sensitive information. The server, recognizing it as a valid message (from an integrity standpoint), would simply process it successfully and move on.

To mitigate this risk, include a time-stamp within the payload as well as within the HMAC’s input data.

HMAC 4 - http://www.geekhive.com 

This time, our hashing algorithm will use the concatenation of the Message and Send Time as input and result in the following hash value:

HMAC 5 - http://www.geekhive.com

Finally, our payload sent to the server will be:

HMAC 6 - http://www.geekhive.com

Our server, concatenating the Message and Send Time in the same manner, will generate the same HMAC value. This solution helps mitigate the risk of a particular message being repeatedly sent to the server by having the server compare the current time versus the Send Time value received on the message, expiring it after a brief period of time. The server has high confidence that the Send Time value has not been altered after the payload was generated by the application code, as shown in the first example. 

Typically, with software, a unique key will be assigned to a physical client, or licensee (not to be confused with the client application.) This key is commonly known as an API Key. In a traditional client-server environment, where the client application is a compiled binary, one can trust that this API Key is sufficiently hidden within the binaries as a result of a compilation process. However, in a web solution where the client application is running as Javascript, at best the application code can be obfuscated, leaving the API Key in plaintext for the browser to consume.

To resolve this, we can instruct the server to validate the origin of the client system by preconfiguring the application code with location authorization written in Javascript.

During initialization, the software would register itself with the server and include the hosting domain. The server would then validate the domain against one of the pre-registered domains and respond with a unique token value associated with that domain.

This unique token would then be included in all subsequent requests made by the application so the server could ensure no conflicts exist. If configured so that unique tokens are not known to the client application until the point of registration (initialization), your system can revoke and re-generate tokens as needed (such as the case if a token were compromised.)

The payload has been slimmed down for simplicity:

HMAC - http://www.geekhive.com

Given an unlimited amount of resources (including time), any security solution can be deconstructed and/or circumvented, but the key is the effort required. By constructing sufficient barriers, if a solution is ever breached, the hope is that it is breached well beyond the period of usefulness for the information that is acquired.

 

1: In theory, the same hash value could be generated using different input values, but the likelihood of this is very low.

 

2: (c) Willard C. Smith & Jeffrey Townes, UNIVERSAL MUSIC-Z TUNES LLC, (ASCAP)

 

Phil Azzi, Developer, GeekHive

Phil Azzi

Technical Lead
Tags
  • Security

Recent Work

Check out what else we've been working on