Home ...

JWT token generation and usage

Ragavendra B.N.
Ragavendra B.N.

JWT or bearer tokens are the goto authentication mechanism in today's online world.

How is JWT token generated?

To understand the JWT token, let us begin by taking a look at the sample token like below.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NjZhMTAxZjllODQxZDIyYzc1ZWEwYjQiLCJpYXQiOjE3MTgyMzk4NjIsImV4cCI6MTcxODI0MTY2MiwidHlwZSI6ImFjY2VzcyJ9.7p4QSTK6GURouBXhIDPzJgqAhYHCaqiDsvGd+iHjL8c

The token has three parts separated by the . operator. The first is the header of the payload describing the method used to create the signature in the last part. The second, lastly is the payload or the message. The header and the payload are the base64 value of the header in json.

One can decode the token on a ~nix machnie by isssuing the below command.

echo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | base64 -d

Where the -d is for decrypt, meaning decrypt using the base64 or alternatively one can go to the Auth0 site and put the above token. The token is decoded to reveal the header and the payload. The header is like

{"alg":"HS256","typ":"JWT"}

Saying, the HS256 algorithm is used to create the signature. The payload can also be decrypted in a similar way which will decrypt to be

{"sub":"666a101f9e841d22c75ea0b4","iat":1718239862,"exp":1718241662,"type":"access"}

To know about the convention used for sub, iat, etc,. One can visit the RFC page.

The last part is signature of both the payload and the header generated with the secret. The secret is specific to the system issuing the token.

How is JWT token signature generated?

In case one needs to create a token with the signature on an *nix machine, one can do so like below using any one of hmac256 or openssl.

jwt_header=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
payload=eyJzdWIiOiI2NjZhMTAxZjllODQxZDIyYzc1ZWEwYjQiLCJpYXQiOjE3MTgyMzk4NjIsImV4cCI6MTcxODI0MTY2MiwidHlwZSI6ImFjY2VzcyJ9
echo -n "${jwt_header}.${payload}" |  hmac256 --binary ThisIsSecret | base64
7p4QSTK6GURouBXhIDPzJgqAhYHCaqiDsvGd-iHjL8c=

echo -n "${jwt_header}.${payload}" |  openssl dgst -sha256 -mac HMAC -macopt key:ThisIsSecret -binary | base64
7p4QSTK6GURouBXhIDPzJgqAhYHCaqiDsvGd-iHjL8c=

You can now see that it matches the last part in the token ( The server used the same secret as well ). One can verify the same in jwt.io as well, updating the secret there and seeing hos the last or the signature part is updated.

How is security achieved?

Using a very strong secret, I quote again "Using a non dictionary strong secret" helps a lot. One can use openssl to generate one like below in their machine again for security purposes.

openssl rand -base64 32
51FBXrqRMjfUTBY6VLWtwSP5trStGU7BzZig+FRxQxk=

The JWT or the bearer token can either be used in cookie or in the Authentication header like Bearer tokenHere.

One should always ensure that the token is short lived, it should never be valid for more than 3 hours maximum. This is to ensure, that even if the token falls into the wrong hands, it is not valid for long. For banking or financial industry, the expiration can be as much as 5 minutes as well. In the last minute or so, the client can request a newer token for the next 5 minutes using the refresh token if needed.

The maximum damage that can be done can be limited to the remaining available time of the token. In order to change any of the values in the payload, the signature has to be regenerated for which the secret is required. This is the main reason to make use of a complex secret as possible.

PS - One may notice = is removed from the signature. This is a RFC requirement to have it removed.