Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating a JWT in node.js

I'm trying to parse and validate a JWT token in node.js based on this sample (authored in .NET): https://github.com/liveservices/LiveSDK/blob/master/Samples/Asp.net/AuthenticationTokenSample/JsonWebToken.cs

Here is my node js javascript that validates the token:

var validateSignature = function(key, claims, envelope, signature) {
    var hasher = crypto.createHash('sha256');
    hasher.update(key + "JWTSig");
    var key = hasher.digest('binary');
    var hmac = crypto.createHmac('sha256', key);
    hmac.update(envelope + '.' + claims);
    var out = hmac.digest('base64');
    console.log(out);
    console.log(signature);
    console.log(out === signature);
}

Now, the very weird thing is - it almost works. Here's the output of the three console.log statements:

pEwNPJ+LUHBdvNx631UzdyVhPFUOvFY8jG3x/cP81FE=
pEwNPJ-LUHBdvNx631UzdyVhPFUOvFY8jG3x_cP81FE
false

It seems suspicious to me that the hashes are both the same except for the +-/_=

Anybody spot my mistake? Something to do with my base64 encoding.

UPDATE

I played some more and there seems to be something funky going on with base64 encoding here. The following code in node js:

console.log(signature);
var b = new Buffer(signature, 'base64');
console.log(b.toString('base64'));

yields:

pEwNPJ-LUHBdvNx631UzdyVhPFUOvFY8jG3x_cP81FE
pEwNPJLUHBdvNx631UzdyVhPFUOvFY8jG3xcP81F

Which seems very odd, right?

like image 775
ConfusedNoob Avatar asked Jan 15 '12 00:01

ConfusedNoob


People also ask

How JWT verify works in node JS?

To verify a JWT, the server generates the signature once again using the header and payload from the incoming JWT, and its secret key. If the newly generated signature matches the one on the JWT, then the JWT is considered valid.

What does JWT verify () do?

Javascript. }); Step 11: JWT verify method is used for verify the token the take two arguments one is token string value, and second one is secret key for matching the token is valid or not. The validation method returns a decode object that we stored the token in.


1 Answers

Thanks to Timothy Meade for commenting and pushing me in the right direction.

Node's Buffer type generates standard Base64 with +, / and =

There is a URL safe base64 encoding as mentioned here: http://en.wikipedia.org/wiki/Base64

It replaces + with -, / with _ and = is optional. The token that is passed on the QueryString (d'uh) is a URL safe version. Hence the difference.

Code was fixed by a simple:

out = out.replace('+','-').replace('/','_').replace('=','');
like image 95
ConfusedNoob Avatar answered Sep 21 '22 04:09

ConfusedNoob