Blog

Json Web Token Using C#?

Json Web Token Using C#?

Introduction

According to jwt.io:

"JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed."

In a nutshell, JWT allows us to exchange data securely using cryptographic algorithms.

When people refer to JWT, they usually mean JWS (Json web signature) which has 3 parts separated by a dot ("."). Although anyone can see its payload. It’s considered secure because the jwt can be verified using the signature part. We can use websites like jwt.io to debug our generated token.

Along with JWS, we could represent a JWT using JWE(Json web encryption) which also adds confidentiality to the result. With this type of encryption, only the consumer knows what is in the payload.

In this post, I will cover only the JWS generated by the HS256 algorithm and reserve JWE for another post for the sake of brevity and simplicity. So, everytime I mention JWT in this post, I'm talking about JWS and not JWE.

If you are interested, you can read more about JWE here.

Jwt structure

Jwt contains of 3 parts:

- Header
- Payload
- Signature

Header

The Header of JWT is a JSON object. This part identifies which algorithm is used to generate the signature, it usually contains 2 fields "alg" and "typ".

For example:

Figure 01: JWT Header example

Figure 01: JWT Header example

The above example states that the Signature will be created using HS256 (HMAC with SHA-256 algorithm) using header and payload as input parameters.

- "alg" is the algorithm used to generate the signature. 

- "typ" is the media content type of the JWT token. According to RFC 7519, Section 5.1 "This parameter is ignored by JWT implementations; any processing of this parameter is performed by the JWT application".

Payload

Payload is also a JSON object containing multiple claims. We have 3 claim types:

- Registered claim names (Defined in RFC 7519). 

- Public claims (Not defined in the RFC 7519 but published here).

- Private claims (Only the JWT producer and JWT consumer know what the claim stands for). For example, we can define a claim like this: "tenantId":"tenant 123" as a tenant id in our multi-tenant application.

Signature

We can create our signature using a symmetric or asymmetric algorithm (defined in our header). For example, if we want to use HS256 to generate our signature, the "alg" in our header should have the value "HS256".

Create Jwt using c#

In this section, we will use HMAC-Sha256 hash function to generate the jwt. 

Before diving into the code, here's the formula of generating the JWT.

jwt = Base64Url(header).Base64Url(payload).Base64Url(signature)

Given the formula for signature as below:

Signature = HmacSha256(key, Base64Url(header).Base64Url(payload))

This formula looks a bit messy but really easy to implement. Keep following me along the post, I will try my best to explain everything.

First, we will define a class for Payload and Header.

Figure 02: Define the Header and Payload

Figure 02: Define the Header and Payload

And also a method to generate JWT. This method takes the header, payload and the secret key. The ‘string’ returned encoded using Base64UrlEncode function

Figure 03: Define the method’s signature for generating the JWT

Figure 03: Define the method’s signature for generating the JWT.

To generate the first two parts of the JWT, we only need to serialize the header and payload, then encode them using Base64Url accordingly.

Figure 04: Defining the helper methods and using them inside the MakeJwt method

Figure 04: Defining the helper methods and using them inside the MakeJwt method

For Json serialization, we will use Newtonsoft and set the NamingStrategy to CamelCase. You can use your favorite json serialization library, but remember to set its naming strategy to CamelCase (refer to the header section above).

Figure 05: Setting json contract resolver to camel case and the SerializeObject helper method.

Figure 05: Setting json contract resolver to camel case and the SerializeObject helper method

Generating the signature is a bit trickier. First, we need to create an instance of HMACSHA256 class using the secret key provided. Then we call ComputeHash on the cipher text which was constructed using the first 2 parts of our jwt. Note that the ComputeHash returns the byte[]. We need to use Base64UrlEncode on this byte array to get the string output as the third part. Finally, we do a string interpolation and return it.

Figure 06: Generating the signature & using it inside the MakeJwt method

Figure 06: Generating the signature & using it inside the MakeJwt method

We can use jwt.io to debug our generated token. Here’s an example of using the code.

Figure 07: Generating the jwt token using our MakeJwt method

Figure 07: Generating the jwt token using our MakeJwt method

Figure 08: Verifying our generated JWT using jwt.io

Figure 08: Verifying our generated JWT using jwt.io

Parsing and verifying Jwt using c#

Decoding and verifying Jwt is also very simple.

First, we split the jwt into 3 parts using '.' as the separator character. The first part should be our header, the second part is the payload and the third part should be the signature respectively. We use Base64UrlDecode method to decode the string, then deserialize the first 2 parts to get the header and payload. 

To verify it, we only need to generate the signature again using the formula above and compare it against the third part of the jwt. In our case, we are using the HS256 algorithm to generate the jwt so we could just hard-code this condition. For general use cases, we must verify using the provided algorithm in the header.

We can use the jwt generated by  jwt.io to check our VerifyJwt method as well.     

    Figure 09: DecodeBase64Url helper method   

Figure 09: DecodeBase64Url helper method         

Figure 10: VerifyJwt method 

  Figure 10: VerifyJwt method        

Figure 11: Try generating a token using jwt.io

Figure 11: Try generating a token using jwt.io

Figure 12: Verifying the JWT using our VerifyJWT method

Figure 12: Verifying the JWT using our VerifyJWT method

Conclusion

In this post, we had an insight into how JWT works, and how to implement and also verify it. Hopefully, we will have a dedicated post for JWE in the future as well.

You can find the source code here.

In conclusion, the exploration of JSON Web Token (JWT) within the context of C# programming on Saigon Technology's blog underlines its significance for enhancing security in web application development.

Follow our newsletter. Master every day with deep insights into software development from the experts at Saigon Technology

Content Manager

Thanh (Bruce) Pham CEO of Saigon Technology

A Member of Forbes Technology Council

Table of Contents

Want to start a project?

Our team is ready to implement your ideas. Contact us now to discuss your roadmap!

get in touch

As a Leading Vietnam Software Development Outsourcing Company, we dedicate to your success by following our philosophy:

YOUR SUCCESS IS OUR MISSION.

about-us

Contact Us