Prepare for a backend job by mastering computer science fundamentals

HMAC and MACs - The Inner Workings of JWTs

By Lane Wagner on Aug 5, 2020

HMACs and MACs are authentication codes and are often the backbone of JWT authentication systems. A Message Authentication Code (MAC) is a string of bits that depends on a secret key and is sent with a message to prove the message wasn’t tampered with. HMACs are a more strict version of MACs that offer additional security benefits.

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.

MAC diagram

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:

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

message = 'my message here'
macCode = sha256('thisIsASecretKey1234' + message)
// send macCode and message

Then the verification by the receiver would be:

// receive macCode and message
if (macCode == sha256('thisIsASecretKey1234' + message)){
  // verified!
}

Note that MACs don’t necessarily need to use a hash function, but a hash can be used as the “signing” mechanism.

A simple path to your career in backend development

The pace of Boot.dev's JavaScript, Python and Go courses has been perfect for me. The diverse community in Discord is a blast, and other members are quick to help out with detailed answers and explanations.

- Daniel Gerep from Cassia, Brasil

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’s possible 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.

HMACs with JWTs

If you’ve ever implemented JWTs for authentication schemes within 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:

hmacCode = sha256('thisIsASe' + sha256('cretKey1234' + '{"email":"lane@34.106.91.234"}'))
header.{"email":"lane@34.106.91.234"}.hmacCode
PUT /users/profile_picture
Authentication: Bearer header.{"email":"lane@34.106.91.234"}.hmacCode

{"new_picture": "http://linktopicture.com/mypic"}

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

Become a backend engineer by building real projects

Related Reading