How to Decode Jwt Token in JavaScript Without Using a Library

How to decode jwt token in javascript without using a library?

Note: this does not validate the signature, it just extracts the JSON payload from the token, which could have been tampered with.

Browser

Working unicode text JWT parser function:

function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));

return JSON.parse(jsonPayload);
}

JWT uses base64url (RFC 4648 §5), so using only atob (which uses base64) isn't enough.

Node.js

function parseJwt (token) {
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}

Library for decoding JWT on client-side

EDIT: It has come to my attention that this answer is incorrect. Please see this answer instead
How to decode jwt token in javascript without using a library?

A JWT is just a dot separated base64 encoded string. You just need to split on the dots and then use atob() to decode. You don't need an external library.

e.g.

var jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";

var tokens = jwt.split(".");

console.log(JSON.parse(atob(tokens[0])));
console.log(JSON.parse(atob(tokens[1])));

Decode Jwt Token in Node - without Library

Actually I have tried it in independent environment and above code works like charm for getting Jwt token pay load

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
const base64Url = token.split('.')[1];const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');const buff = new Buffer(base64, 'base64');const payloadinit = buff.toString('ascii');const payload = JSON.parse(payloadinit);console.log(payload);

How to validate JWT without library

Please read more about it here https://jwt.io/introduction.

Basically, the token is base64-encoded so you can easily decode to read the content. Therefore it shouldn't include the credentials but only the id to identify the user (and extra data if needed). Then you can validate it using your secret key, it's depending on the algorithm you chose when issuing the token as well - here is HS256.

The last part of the token after dot (.) is the signature you need to validate. If it is correct then you know the token is valid and the current user from what you see inside the token.

For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

Use the library that you use to issue the token to validate this, best to read its documentation.

For example, this is the content I decoded from your token:

{
"iss": "localhost",
"name": "Vinicius",
"email": "vinicius@hotmail.com"
}

So if you validated the signature you can believe that the user who is using this token is vinicius@hotmail.com

Decoding JWT tokens without the secret

There are two ways in which a public/private keys can be used by a JWT: signing and encryption.

If you use a private key for signing, it allows for the recipient to identify the sender of the JWT and the integrity of the message but not to hide its contents from others (confidentiality). Note that it would be the sender's private key that is used to sign the JWT and produce a JSON Web Signature (JWS) object. Apparently that applies to the JWT that you're looking at.

When using a public key for encryption it can be used to hide content from anyone but the intended recipient. The result is a JSON Web Encryption object. Note that it would be the public key of the recipient that is used to encrypt the JWT. Apparently that is what you're looking for.

See: http://jose.readthedocs.org/en/latest/

How to decode JWT of STIR/SHAKEN into JSON object?

The token is actually signed with the ES256 algorithm, not HS256.
The public key certificate is provided in the URL that is given in the header in the X5U-claim, which is a URL pointing to a X.509 certificate.
For the demo below and to keep it simple, I saved the certificate to a file name x509.pem.

Here is a simple demo (based on the examples in the Jose-JWT GitHub repo:

using Jose;
using System;
using System.Security.Cryptography.X509Certificates;

namespace JoseJWTES256X509Test
{
class Program
{
static void Main(string[] args)
{
string token = "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9jci5zYW5zYXkuY29tL1RlY2hub2xvZ3lfSW5ub3ZhdGlvbl9MYWJfNTk5SiJ9.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyIxNDc5MjM5OTcwMyJdfSwiaWF0IjoxNjU5NTIxNDU5LCJvcmlnIjp7InRuIjoiMTQ2OTUwMTYwNzAifSwib3JpZ2lkIjoiOTIzNDIxOTgtMTMxNC0xMWVkLWExM2QtYmRjMWMxZDI4ODg4In0.8RF_eaVKeGGyjet4lujwPz0J_XBdtwkSKrnrOq7-pA6ODtJPD1parLgimEpDUyzSravtTaxuACxBz4yrKtMZgw";
var publicKey = new X509Certificate2("x509.pem").GetECDsaPublicKey();

string payload = Jose.JWT.Decode(token, publicKey, JwsAlgorithm.ES256);

Console.WriteLine(payload);
}
}
}

As a result the token will be verified and the payload will be printed. In case of a failed verification, the Decode-function would throw an exception.

As a side note: the Decode-function actually verifies the signature before decoding, and that's for what it needs the key. For the actual decoding, no key is needed because the payload is just Base64Url encoded. That's why https://jwt.io can also decode the token without knowing the key.

How to decode jwt token in POSTMAN?

Postman supports cryptojs library : https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#using-external-libraries

Add below example to postman test script:

let jwt = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0.UsrGn95rk5DStcC_WwIr3WIv5rHe2IApX56I58l8uyo`

a = jwt.split('.');

//a.forEach(function (val) {
var words = CryptoJS.enc.Base64.parse(a[1]);
var textString = CryptoJS.enc.Utf8.stringify(words);

console.log(textString)
//})

Output:

Sample Image

The hmacSHA256 is not an encryption algorithm but an Hashing algorithm so there is no way to decode it as hashing is one-way function.

as the last part is in the form

HMACSHA256 of ( base64(header) + "." + base64(body) )

you can try creating it and equating both are equal



Related Topics



Leave a reply



Submit