Hmac User Authentication

HMAC, or Hash Message Authentication Code, provides an easy mechanism for verifying both user authenticity and that a message hasn't been tampered with, without the overhead of encrypting the data... and, indeed, without much more overhead than a secure hash. Do note that HMAC doesn't offer privacy.

The basic idea of HMAC is that, for any secure cryptographic hash H: H(APPEND(KEY,MESSAGE)) will be extremely difficult to create without the key. So, by delivering APPEND(MESSAGE,H(APPEND(KEY,MESSAGE)), someone with the key on the other end can both verify the message contents (that nothing has been altered) AND verify that the message was created by someone with the same key.

The actual HMAC algorithm is only slightly more complicated, performing a hash twice in order to resist some forms of cryptographic analysis. It is:

HMAC Algorithm (http://en.wikipedia.org/wiki/HMAC)

  HMAC(H,KEY,MESSAGE) = 
  let PKEY = PAD(KEY) with ZEROES to BLOCKSIZE(H)
      IPAD = VECTOR(0x5c, BLOCKSIZE(H)) XOR PKEY
      OPAD = VECTOR(0x36, BLOCKSIZE(H)) XOR PKEY
  in H(APPEND(OPAD,H(APPEND(IPAD,MESSAGE))))

And the delivered result is APPEND(MESSAGE,HMAC(H,KEY,MESSAGE)). Note that 'H', in practice, is most often SHA1 or MD5, and BLOCKSIZE(H) is the obvious (64 bytes for MD5 or SHA1).

Use of HMAC by itself doesn't prevent replay attacks. To prevent replay attacks, a unique message-identifier must be part of each message. One can do this in the typical fashion by having the server create a unique (nonce) server-session-ID and having the client create a unique (nonce) client-session-ID (or more than one) and then having the client number its delivered messages. The server can allow the client to open any number of sessions under the server-session-ID (the ability to open more than one is very convenient for client scripts across multiple browser frames) and simply tracks the last message send by each one, ensuring that it is not identical to any previously received message id (usually by requiring increments and ensuring a greater-than relationship, possibly with some small buffer to allow for for delayed messages).


HMAC Sessions Example

HMAC starts by assuming secret shared keys are already held. This could be a plaintext password, but I'll assume that the server is storing something like a table: PASSWORDS(USERNAME,REALM,PASSHASH,SALT). The USERNAME is unique. Other data, such as e-mail and whether a password reset is required could also be denormalized into this table, but such isn't required.

The use of 'SALT' protects against dictionary attacks on the password file. One could use a pseudorandom string as 'SALT', or could use something like a URI for an image (e.g. a particular smiley face from smiley central). Or it could be a combination of the two (e.g. <img uri="smiley.gif" alt="salt=qxZz3y9"/>). There is no real security advantage in using an image URI to a random string (since it is vulnerable to Man in the Middle attacks), but the ability to present the image to the user is a nice flavor touch and does raise the bar just slightly for potential spoofers. (Bank of America uses something similar, called a 'SiteKey', that offers no protection whatsoever but does offer a fine illusion of protection.) The use of SALT does have a cost, in that the server must be the first to provide authentication information (since the client isn't going to remember the SALT), but, as will be seen, that suits my purposes just fine, because in this example the server is authenticated first.

The 'PASSHASH' is a secure, cryptographic hash, created by a very predictable formula... such as: SHA1(USERNAME + "@" + REALM + ":" plaintext password + ":" + SALT)... or even HMAC(SHA1,plaintext password,(USERNAME + "@" + REALM + ":" + SALT)). Keeping passwords hashed in this manner is also protection against abusers of the PASSWORDS table itself, since it keeps them from seeing the password. Assume secure user creation, e.g. via a fully encrypted connection like SSL, possibly with validation of user through paypal or a credit-card service. This gets the PASSHASH into the remote database in a secure manner. Technically, the plaintext password never needs to leave the client machine.

Anyhow, since the server only knows 'PASSHASH', 'PASSHASH' will be the secret key between the client and the server. PASSHASH must never be delivered across the network in unencrypted form, but CAN be used to encrypt and decrypt small random blobs (e.g. a session key).

The Full Web Login Process:

Fast Login Process: The Advantages: The Disadvantages:


CategorySecurity


EditText of this page (last edited November 23, 2014) or FindPage with title or text search