How to make your own JWT

udaiveer singh
Code Wave
3 min readDec 23, 2015

--

JWTs or Json Web Tokens seem to be all the hype for stateless session management. It can be quite easy to just import a JWT library and use it without knowing much of the internals, but sometimes with crypto this can be quite dangerous.

In this blog I will teach you how to implement your own JWT that is just as secure and robust as the libraries you import. Obviously we will not try and implement all of RFC7519, but this will be the minimum viable JWT that can be used in your online applications.

Prerequisites

Just like any other technology JWTs require some knowledge of other libraries/cryptography. In this blog I will also talk about all the necessary crypto needed for JWT’s.

What a JWT is made of

JWT has 3 parts all concatenated by a “.” symbol that is used to split the toke for parsing. The JWT is also base64 encoded. The reason that it is 64bit encoded is that it contains character sets of mostly letters and numbers that can be printed, and it does not have “.” in the language which is out split character.

64Bit encoding: (A-Z) (a-z) (0–9) (+) (/) The (=) and (==) is used for padding

Sample JWT

Now it should be pretty obvious that this jwt is 64 bit encoded. Let’s split the JWT by calling JWT.split(“.”).

head:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

body:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature:TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Header and Payload

decode_64(head) : take the 64 bit strings and give the standard UTF-8 character encoding back.

decode_64(body): does the same thing with the payload that is used in the JWT

decode_64(signature) will not give back a human readable strings because it was hashed, but I tried it any way and I got L•@÷“«3±6p›ßDL±ÃpGñŽ†áN4X{

HMAC-SHA256

MAC stands for message authentication code and SHA256 is a 256 bit hashing algorithm that takes any string and outputs an almost unique(32-byte) hash. Now putting those two concepts together a HMACSHA256 is a Message Authentication Hash function that takes a message and an key and then uses that to produce a fingerprint like 32byte string that can be used to uniquely identify the message. Same message hashed with different keys give a separate output.

Implementation in Node.js

encode: takes a json object (payload) stringifies it and then follows the JWT algorithm and return a JWT string.

decode: takes a JWT string object takes the head and payload and computes the signature and compares if the two signatures are equal and return the payload as an object if true and false if they are invalid.

In our implementation the head is kind of pointless because the only algorithm is always using HMACSHA256, but it does not hurt to keep it in for future extensions of the library.

This working implementation of JWT can be found on my Chat Application hosted on AWS. Extending this to include the time expiration should be quite trivial, but if you are going to implement anything more than symmetric key JWT for deployment I say leave that up to the professionals.

Additional Resources

--

--