You might have heard of JWT (JSON Web Token) which are one of the most amazing things in the internet to me. They are great to store information that you want to make sure is the truth (like a user ID to authenticate access).

You are probably familiar with JWT in one way or another if you are reading this post. A quick review nevertheless. A great place to comfortably understand those tokens better is https://jwt.io/. Here a screenshot from a token:

We see the three different colours on the left, corresponding to the three different colours on the right, showing the different parts of the token.

In this post I would like to point your attention to the Header. More specifically the "alg": "HS256".

HS256 (which exactly is HMAC with SHA-256 encryption) is a symmetric encryption. This means that the key you use to encrypt and decrypt the payload is the same one. Maybe you've been using a "SECRET" variable for your JWT cookie 🍪? This secret is exactly what I am talking about here.

But there are great news for everyone who wants to make it a bit more complicated (or needs to). JWT also supports RS256 🎉

RS256 (RSA Signature with SHA-256) is an asymmetric encryption. Which means you have a Private/Public key pair. This is just perfect when you have one server that is your Fort Knox (holding the private key and issuing the JWT) and another server (or maybe many other servers) that should validate those (using the public key to validate the JWT).

(SOURCE)

So you see, if you are playing in an ecosystem RS256 is something you will consider using sooner or later - and it's really beautiful, because you can share JWTs with your half-criminal friend and you don't need to send him/her your secret. 😁 🤩

But there are some difficulties when it comes to handling RS256 that I found myself in when using it for the first time. It took me a day to get my head around it. But with the secret knowledge you'll gain here, it will take you seconds.

1 Handling the Key Pair

HS256 are normal strings and there is no big challenge in handling them. RS256 are a bit special. They normally look like this:

Note they have those special headers and footers e.g.

-----BEGIN PUBLIC KEY-----
and
-----BEGIN RSA PRIVATE KEY-----

Here comes the deal:

Those headers need to be in a new line! This is why you will often find people storing these in files and reading the files from the disk. But you might have situations in which you need to read the RS PRIVATE KEY or the PUBLIC KEY directly from a file. E.g. to load it from a .env file.

In this case there's a simple trick.

Make sure your tool supports the newline symbol ( \n ). .env supports it if you add double quotes ( " ) around the string and write it like this:

PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIJJwIBAAKCAgEA8sqA.........../BSOzjc4Yups04Rhu0b4csro2hxECggEANDlIbkYxESYPTdKGV7T8mXPl+w==\n-----END RSA PRIVATE KEY-----"

To make sure it's clear here a picture how it would look.

In case you are deploying your stuff to Heroku: It directly accepts multi-line strings as env variables. Just copy and paste it there.

2 Bonus Tip: Generate Key Pair

Generating a private public key pair is super simple. Even simpler when you are on a unix system:

# Create a private key (Don't add passphrase)
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key

# Create a public key
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub

# Print the private key
cat jwtRS256.key

# Print the public key
cat jwtRS256.key.pub

(SOURCE)

On windows you better use cygwin or another way to run ssh-keygen as well. (SOURCE)

That's it. Now you can enjoy asymmetric keys for JSON Web Tokens. Cheers!