November 04, 2013

Message Security for Your Web Api

So lately I have been studying security. There are a few basic models: 1) basic authentication with SSL, 2) OAuth 2 and 3) HMAC Authentication. There are a few things to keep in mind with those models, and the main one I will talk about in this article is HMAC.

I wanted to start out the gate, on my new project, with security in mind. Many times security is an after thought that we just leave to the wind to decide. The fastest security model to implement is basic authentication with SSL. While it does provide you some comfort, keep in mind that this security model has some downsides. One being that man in the middle attacks can expose your api to a security breach. To resolve this, you could use OAuth 2.0, but there is much setup, and it is still a growing standard. Mind you, OAuth still needs a SSL connection to protect the credentials. What if you need a message level security? You could implement HMAC Authentication to help with that.

I have looked at some good articles from Piotr Walat and others on implementing HMAC Authentication. While they have put a good in-depth article together, I feel like most articles I have read are a bit complex. This article, I thought, why not just put in simplest terms. So let’s get to how to HMAC

What pieces do I need to do?

First, MD5 hash all of your content and throw that into the header of your request/response header (Content-MD5). This will prevent someone from tampering with your message.

Next, identify all the headers that change frequently. This is so the hashing algorithm is harder to crack. Think these headers:

  1. 1. X-ApiAuth-Username (your user name for the api)
  2. 2. the http method being used
  3. 3. Date (in UTC)
  4. 4. Request URI
  5. 5. and any other frequently changing items
Be sure to include the Date, as we want to limit play back attacks that can allow someone to hack the api’s private hash.

Lastly, include the private key in the hash and assign it to your authentication header as the signature: (Authorization: ApiAuth [your hash that you created])

Because the hash is private, nobody can find out the secret, even in plain text. This eliminates the need to sign your messages with SSL. Remember, this is only if you need this level of encryption, as it is expensive to do, than the previous 2 security schemes. So combine this, with Piotr’s website above, and you should be able to knockout a good security mechanism for your web api.