In Focus

Understanding JSON Web Tokens (JWT)

In this article, we are going to understand about JSON Web Token which is known as JWT.

Introduction

 
JSON Web Token is known as JWT. It is an open standard that is used for transmitting information between parties as a JSON object. JWT is a secure way for Authentication and Authorization because it is digitally signed. It can be secured by using a secret key or a public and private key applying different types of algorithms. It is supported by most of the application like .NET, Java, Python, PHP, Ruby, JavaScript, Node.js and etc. JWT can be used as the query string, cookies, HTTP header, or body parameter. This is a very useful way for single sign-on (SSO).
 

Structure

 
JWT consists of three major parts:
  • Header
  • Payload
  • Signature

These three parts are separated by dots (.) and all are in Base64Url encoded format as below.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3ZpdmVra3VtYXIuY29tIiwiaWF0
IjoxNTQ0MDM0Mjg3LCJleHAiOjE1NzU1NzAyODcsImF1ZCI6Ind3dy52aXZla2t1bWFyLmNvbSIsInN1
YiI6InZpdmVrQHZpdmVra3VtYXIuY29tIiwiTmFtZSI6IlZpdmVrIEt1bWFyIiwiUm9sZSI6IkFkbWluIn0.JC
iVwlHWrgxZHrdGjGdlMH7rMij2Atd6rw0C7reVnd8

Header

It usually consists of two parts -

  1. Typ – generally it will be JWT
  2. Alg – hashing algorithm

In the above token, the header is the first part before the first dot (.), which is in Base64Url encoded format as below.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

When we will decrypt Base64Url above header then we will get JSON like below

  1. {    
  2.   "typ""JWT",    
  3.   "alg""HS256"   
  4. }  

Here “typ” is used for identifying the token type which will generally JWT and “alg” is used for identifying the hashing algorithm which is involved in creating a signature for JWT.

Payload

In the above token, the Payload is the second part, between the first and second dot(.), which is also in Base64Url encoded format as below. 

eyJpc3MiOiJodHRwczovL3ZpdmVra3VtYXIuY29tIiwiaWF0IjoxNTQ0MDM0Mjg3LCJleHAiOjE1
NzU1NzAyODcsImF1ZCI6Ind3dy52aXZla2t1bWFyLmNvbSIsInN1YiI6InZpdmVrQHZpdmVra3
VtYXIuY29tIiwiTmFtZSI6IlZpdmVrIEt1bWFyIiwiUm9sZSI6IkFkbWluIn0

The payload contains the claims. Claims are the statements about an entity, generally user, and also it contains additional metadata.

There are three types of Claims.

  1. Registered Claims
  2. Public Claims
  3. Private Claims

Registered Claims

These are a set of predefined claims which are recommended and we have to use it while creating the token, some of them are very useful while validating the token by another service but it is not mandatory.

Below is the example of registered claims,

  • iss (Issuer)
    It identifies the principal that issued the JWT. Generally a DNS name.

  • sub (Subject)
    It identifies the principal that is the subject of the JWT. The subject is unique in the context of the issuer. It is generally user id or email id in the context of the user.

  • aud (Audience)
    It identifies the recipients that the JWT is intended for. In the general case, the "aud" value is an array of case sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value may be a single case-sensitive string containing a StringOrURI value.

  • exp (Expiration Time)
    It identifies the expiration time on or after which the JWT is no longer valid.

  • nbf (Not Before)
    It identifies the time before which the JWT must not be accepted.

  • iat (Issued At)
    It identifies the time at which the JWT was issued

  • jti (JWT ID)
    It is a unique identifier for the JWT, basically we can say it is an identity key of each JWT.

Public Claims

These can be defined at will by those using JWTs. However, in order to prevent collisions, any new claim name should either be registered in the IANA "JSON Web Token Claims" registry or a value that contains a Collision-Resistant name. In each case, the definer of the name or value needs to take reasonable precautions to make sure they are in control of the part of the namespace they use to define the claim name.

Examples of collision resistant namespaces include:

  • Domain name
  • UUID

Private Claims

These are the custom claims, a producer and consumer are using for sharing the information. These claim names can be any things except registered claims or public claims.

If we decrypt Base64Url of above Payload, then we get JSON like below,

  1. {  
  2.     "iss""https://vivekkumar.com",  
  3.     "iat": 1544034287,  
  4.     "exp": 1575570287,  
  5.     "aud""www.vivekkumar.com",  
  6.     "sub""vivek@vivekkumar.com",  
  7.     "Name""Vivek Kumar",  
  8.     "Role""Admin"  
  9. }   

Signature

In the above token, the Signature is the last part after the second dot(.)

JCiVwlHWrgxZHrdGjGdlMH7rMij2Atd6rw0C7reVnd8

Signature is responsible for validating the JWT.

To create the Signature part, we need the encoded header, the encoded payload, and a secret. Now we can use an algorithm to create a signature. Either we can use one secret key known as symmetric cryptography or we can use Public-key cryptography known as asymmetric cryptography for signing. It’s totally up to us which algorithm we are going to implement to create a signature

Below is some algorithm which is used to create a signature,

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • ES256
  • ES384
  • ES512
  • PS256
  • PS384

In this above token, we are using HMAC SHA256 algorithm known as HS256 (symmetric key algorithm) so for that, we have to use the following way

  1. HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)  

Now we dig it more so that we can understand it in the more easy way.

First, we combine the encoded header and encode payload as below.

  1. encodedHeaderPayload = base64urlEncode(header) + “.” + base64urlEncode(payload)  

Now we use hashing function as per our choice. hashedData = hashFunction( encodedHeaderPayload, secret ) In this example, a secret is a string which we want to pass for encryption. Now the final part is converting the hashedData into base64urlEncode format as below.

  1. signature = base64urlEncode(hashedData)  

So putting all three components together as below

  1. header + “.” Payload + “." + signature  

We can use https://jwt.io to see JWT header and payload information and also we can verify it like below

JSON Web Tokens

When to use symmetric key algorithm and asymmetric key algorithm

 
Symmetric key algorithm
 
If we want to create a token and want to verify it ourselves,  only at that time can we use symmetric key algorithm, which means authentication server and application server are same.

Asymmetric key algorithm

If we want to allow a third party application to verify our token, we can use asymmetric keys and share the public key with the third parties. As public keys cannot be used to sign so that no one can forge a valid token with custom claims. The way we share the public key is up to us.

Example - Google keys at here.

How Do JSON Web Tokens Work

First of all, If a user wants to get a JWT then the user has to provide their credentials as a part of authentication and after successful logs, JWT will be returned.

Now, whenever the user wants to access a protected resource from the server then the user agent sends the JWT generally, it is in Authorization header using the Bearer schema.

The content header looks like below

  1. Authorization: Bearer <JWT>  

JWT is a self-contained way for securing transmitting information between two parties so it’s a stateless authentication mechanism. Generally, it contains all the necessary data so we don’t need to call the database. Mostly we use Role or Scopes in the payload to access the protected resources.

There are many open source libraries to support JWT in most of the languages such as .NET, Java, PHP, Python, Ruby, Go, Scala, Swift, C, C++, JavaScript and etc.

Conclusion

In this article, we got the understanding of JSON Web Tokens (JWT) and its benefits.

We can choose algorithm as a symmetric key algorithm or asymmetric key algorithm as per our requirements.

You can also read other articles on my personal blog here.

If you have any suggestions or questions, please mention them in the comments section.