I recently had to generate a JSON Web Token (JWT) as a response from an login request to an api. The idea is to POST
the user’s credentials from a mobile app, and to respond with a JWT. The mobile app can then verify that the user has logged in correctly.
A quick introduction to JWT
But let’s step out for a moment. What is a JWT exactly? According to jwt.io, a JSON Web Token is
an open, industry standard RFC 7519 method for representing claims securely between two parties.
It’s used often as an access token for a client. The client will request access by providing the username and password, and the server will return an access token. A JWT is just an implementation of an access token. The interesting thing about JWT’s is that they can contain data. Things you would include in the token are:
- when the token expires
- what rights the users has
- …
After the client receives the JWT, it should include it with any subsequent request. The server can then decrypt the JWT using the same secret as the client, and by doing that, can see the original contents of the token. If the client tampered with the token, the decryption won’t work correctly. This has the benefit that the client can’t extend the expiration date, add new rights, etc.
For more information about this, read the introduction on jwt.io and/or this great article.
Generating a JWT
So how can you generate a JWT? First of all, I recommend using an external library like the aptly named JWT.
UPDATE: The JWT package now supports .NET Framework 3.5 and up, so the code below is no longer necessary. It will still work, but I believe using a library is a better way to go.
But in my case, I was stuck on .NET 4.5.2 and the JWT package no longer supports this. In such a case, you can use the System.IdentityModel.Tokens.Jwt package.
First, we need a header:
var header = new { alg = "HS256", typ = "JWT" }; var headerPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header));
I’m using JSON.Net to get the string representation of my object, and the Base64UrlEncoder
.
Now that we have the header part, we need the payload part. The code is similar:
var payload = new { userId = user.Id, userEmail = user.Email, userName = user.UserName }; var payloadPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payload));
Now all we need is a hash of headerPart.payloadPart
:
var secret = "my-secret"; var sha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)); var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes($"{headerPart}.{payloadPart}")); var hash = Base64UrlEncoder.Encode(hashBytes);
And then the JWT:
var jwt = $"{headerPart}.{payloadPart}.{hash}";
What this gives us is a string of text containing three parts: the base64url encoded header, the base64url encoded payload, and a hash of those two. Check out the jwt.io debugger for an example. It’s also a useful tool to test your implementation.
Hi Peter,
This is a great article, thank you.
I have one question though, is there a way to generate a JWT like this but using a JSON Web Key (public key) to do the encryption?
Thanks.
Hi Alejandro,
Thanks for the kind words. I’d have to look into it, but I noticed that the JWT package now supports .NET Framework 3.5 and up. I recommend you use this package, if possible. Let me know if you’re stuck and I’ll look into it.
In vb.net ->
Dim header = New Dictionary(Of String, Object)() From {
{“alg”, “HS256”},
{“typ”, “JWT”}
}
Dim payload = New Dictionary(Of String, Object)() From {
{“iis”, “key”}
}
Dim headerPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header))
Dim payloadPart = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payload))
Dim secret = “secret”
Dim sha256 = New System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(secret))
Dim hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes($”{headerPart}.{payloadPart}”))
Dim hash = Base64UrlEncoder.Encode(hashBytes)
Dim jwt = $”{headerPart}.{payloadPart}.{hash}”
Return jwt
My generates JWT return Not Valid with VB.NET version
Thats cool !
Can you please guide me how can I validate this JWT token in C# without using any external library!
Interesting question, although I would recommend using a library. But I don’t know your situation of course. This is what would work:
var hashPart = input.Split('.')[2];
var payloadPart = input.Split('.')[1];
var headerPart = input.Split('.')[0];
var sha256 = new HMACSHA256(Encoding.UTF8.GetBytes("my-secret"));
var expectedHashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes($"{headerPart}.{payloadPart}"));
var expectedHash = Base64UrlEncoder.Encode(expectedHashBytes);
Console.WriteLine(hashPart == expectedHash);
Try it out yourself! Use a JWT that is correct and it should write true to the console. If you tamper with the JWT, you’ll get false. Let me know if you need more help.