In this exercise we'll use two separate browser windows on https://jwt.io. In window1 we’ll be generating our JWT token and in window2 we’ll be verifying it. Instead of a shared secret we'll be using asymmetric keys.

A great learning source for JWT can be found here https://www.youtube.com/watch?v=7Q17ubqLfaM&t=588s

Generate a private key as follows:

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

Now extract the public key

openssl rsa -pubout -in private_key.pem -out public_key.pem

Now carry out the following steps in window1

  • set the header as {"alg": "RS256”, "typ": "JWT”}
  • set the payload as {"sub": "1234567890”, "name": "Bob Clarke”, "iat": 1516239022}
  • Paste the private and public keys into the relevant windows (including the BEGIN and END markers) - NOTE, at this stage you don’t actually require the public key as we’re only generating the token and not validating it.

This will generate the following token:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJvYiBDbGFya2UiLCJpYXQiOjE1MTYyMzkwMjJ9.An3zJCNTsAc0w1Lx8vEcBWiPOsJVOrtyFJFgHPKvn64iTvDvY9yDABjKS3MGLZtboLoT62K1LsqA0MyZA_xLTObAwMsc_agg1U49MDREtaGsmaakaRozVtysOM4P0ixCDrbhlYKfS2jL0uUgRwDVEw6AuSl3ZZHPCp1dS0FMtiEu_YFHTG4wy_qt7WO5KufvZ1ftFHLbXXjiQk7L4M2JL7iuzFRMJIlrWpsJisKtyJzdjocE0PKLqQJV8DjLYtGm_DYvSpnaGN9tf6A9KtFybEwg0d6bOMvW7fK7SE0W4YMtk32Sj3X3aXT0UW_ztbymDVd4-i8HMawfIh_2SKKFDw

The diagram below shows how a JWT Token is generated:


It’s important to note that this token is not secret, i.e it’s just base64 encoded and therefore anyone can take the red part and simply run it through base64 -D to decode it (example below):

echo "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJvYiBDbGFya2UiLCJpYXQiOjE1MTYyMzkwMjJ9" | base64 -D ; echo 
#=>{"sub":"1234567890","name":"Bob Clarke","iat":1516239022}

So, secrecy is not what we’re after here, what we’re after is message integrity, i.e. making sure not has not been tampered with. To verify message integrity, carry out the following steps in window2:

  • paste the token into the “Encoded” box on the left
  • You’ll notice that the header and payload are decoded normally (i.e, as mentioned above, secrecy is not the aim here) however you’ll also see that there’s a big red message at the bottom saying Invalid Signature (see image below)


To verify whether the message is valid (i.e that it has not been tampered with) we need to paste in public key. The process for token verification is shown in the diagram below:


And here’s the result in window2 with the signature verified and therefore message integrity:


Toptal ref