Blog

How-To: Replacing HMAC Secrets with RSA Keys to Validate Tokens

Mon, Jun 11th, 2018 | Michael Bettendorf

Akamai’s JSON Web Tokens (JWT) validation capability uses RSA-256 (see the RSA cryptography specifications here) to validate the digital signature of a token. We elected to use the RSA algorithm over HMAC because we did not feel that passing secrets around was very secure. However, we recognize that many tutorials and examples of JWT implementations use HMAC shared secrets for the sake of simplicity.

Fortunately, it's not difficult to use RSA keys in place of an HMAC secret. Just follow the five steps below:

1) Generate a public and private key pair (do not use a password)

 $ ssh-keygen -t rsa -b 4096 -f jwtRS256.key 
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Your identification has been saved in jwtRS256.key.
Your public key has been saved in jwtRS256.key.pub.
The key fingerprint is: SHA256:fvXJDhzx9vOpLvvkfzPVmnOgjYnIbcHzDWtgpYvb+M8
The key's randomart image is:
+---[RSA 4096]----+
|                 |
|                 |
| .               |
| .o              |
| S. oo o .       |
| . Bo.=.oo       |
| ..=.BoX+=o      |
| ++=oXo*o*       |
| o+o+E=+==       |
+----[SHA256]-----+

$ openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub writing RSA key

2) Install NodeJS

To proceed with the steps below, you will need to have NodeJS installed either as a native binary or via Homebrew.

3) Install the jsonwebtoken NPM

Run the following command to install the package globally:  

$ npm install -g jsonwebtoken

 

4) Copy the NodeJS code below into a file called “create.js”

var jwt = require('jsonwebtoken'); fs = require('fs') // get the private key var privateRsaKey = fs.readFileSync('jwtRS256.key'); // sign the token with the private key var token = jwt.sign({ expiresIn: '1h'}, privateRsaKey, { algorithm: 'RS256'}); console.log(token);

 

5) Run create.js to create a JWT

 

Running this code will generate a sample JWT for you that expires in 1 hour:

Now that you have a shiny new token, copy it into a text file for safe keeping. Then navigate to JWT.io to inspect the token and verify that it contains the proper claims. You do this by pasting in the token into the “Encoded” field. Then take the public key (public.pem) that you generated and paste its contents into the Public Key section. Do the same copy/paste operation of the private key (private.pem) into the Private Key field. As you can see in the screen capture below, the token should validate successfully with a “Signature Verified” message in blue at the bottom, like so:

Now that we know we have a valid, working JWT, the final step is to integrate the public key with Akamai API Gateway to enable validation. Simply upload the public key via API call or using the API Gateway interface in the Akamai Luna Control Center, as seen here:

Once the RSA public key is in place, you can start configuring validation of JWT claims. Akamai will then use the public key to validate the digital signature on every request it receives.

Jeff Costa is a senior product manager at Akamai Technologies.