paint-brush
HMAC and MAC Explained: How To Build Secure Authentication With JWTsby@wagslane
4,953 reads
4,953 reads

HMAC and MAC Explained: How To Build Secure Authentication With JWTs

by Lane WagnerMay 11th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

HMACs and MACs are authentication codes that allow receivers of messages to know who the sender was (authentication) A JWT (when using HMAC as the signing scheme) is basically just an HMAC message where the message data is a JWT object. An HMAC uses two rounds of hashing instead of one (or none) Each round of hashing uses a section of the secret key. We call this a length extension attack. No known extension attacks are known against the current HMAC specification.

Company Mentioned

Mention Thumbnail
featured image - HMAC and MAC Explained: How To Build Secure Authentication With JWTs
Lane Wagner HackerNoon profile picture

HMACs and MACs are authentication codes and are often the backbone of JWT authentication systems. Let's take a look at how they work!

MAC - Message Authentication Code

MACs are exactly what they sound like; small codes that allow receivers of messages to know who the sender was (authentication). A MAC code is calculated by using a message and a secret key as inputs. Anyone who has a copy of that secret key can then verify that that code and message were created by someone with the same key.

One way this is accomplished is by using a hash function, for instance, SHA-256. Simply put, a hash function takes an input and then returns an output, where:

  • The output is very unlikely to be the same for different inputs
  • The output is always the same for the same inputs
  • The output is not predictable - changing the input in any way results in a seemingly random change to the output

Given this, a naive example of MAC generation by the sender could be:

macCode = sha256('thisIsASecretKey1234' + 'my message here')

Then the verification by the receiver would be:

macCode == sha256('thisIsASecretKey1234' + 'my message here')

Note that MACs don't necessarily use a hash function, but a hash can be used as a "signing" mechanism. For a further reading look at the MAC Wikipedia article.

HMAC - Hash-Based Message Authentication Code

An HMAC is a kind of MAC. All HMACs are MACs but not all MACs are HMACs. The main difference is that an HMAC uses two rounds of hashing instead of one (or none). Each round of hashing uses a section of the secret key. As a naive example:

sha256('thisIsASe' + sha256('cretKey1234' + 'my message here'))

Which is a simplified version of the function given in RFC-2104.

Why use HMAC? Why do we need to hash twice?

With many hash functions, it is relatively easy to change the message (without knowing the key) and obtain another valid MAC. We call this a length extension attack. No known extension attacks are known against the current HMAC specification.

To read further about HMACs take a look here.

HMACs with JWTs

If you've ever used JWTs for authentication schemes on a web app, then you know that JWTs are wonderful for keeping track of who is who. A JWT (when using HMAC as the signing scheme) is basically just an HMAC message where the message data is a JSON object.

The interesting thing about the JWT system is that the sender and the receiver of the JWT are typically the same entity, that is, the webserver. Look at the following example:

  • User gives the server an username and password
  • Server verifies the username and password are correct
  • Server generates a JWT using HMAC:
hmacCode = sha256('thisIsASe' + sha256('cretKey1234' + '{"email":"[email protected]"}'))
  • The server responds with the following (decoded) JWT:
header.{"email":"[email protected]"}.hmacCode
  • User decides to update his/her profile picture by sending the following request:
PUT /users/profile_picture
Authentication: Bearer header.{"email":"[email protected]"}.hmacCode

{"new_picture": "http://linktopicture.com/mypic"}
  • Server parses the JWT. The JWT says the user is "[email protected]"
  • The server verifies that the user really is Lane by validating the HMAC code, because only someone with access to the secret key 'thisIsASecretKey1234' could have made the HMAC code that corresponds to the '[email protected]' message
  • If the verification is successful, then the server updates Lane's profile picture

Because this is a very basic example of how JWT's work, it skips over some implementation details. However, if you want to learn more about the specifics, take a look at the explanation on jwt.io.

If you feel that I missed anything important, or have any questions, feel free to contact me on twitter!

Previously published at https://qvault.io/2019/12/12/hmac-and-mac-explained-simply-building-secure-auth-with-jwts/