Search code examples
node.jsjwtjson-web-token

jsonwebtoken verify fails when the secret is directly provided in the program


I am trying to verify and decode a json web token using jsonwebtoken npm, using the following code snippet:

var jwt = require('jsonwebtoken');
var fs = require('fs');

var encoded = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJsb2dpbklkIjoicm9vdCIsInVzZXJOYW1lIjoicm9vdCIsInJvbGUiOiIwIiwic3RhdHVzIjoiMSIsInBhc3N3b3JkIjoiYWNiM2UxNDFkODgzMTA2ZGUyZjMwZDQ2ZTc2YzA5Y2YiLCJuYW1hayI6InJvb3QiLCJsYXN0TG9naW5UaW1lIjoibnVsbCIsImVtYWlsIjoicm9vdEBlY3AuY29tdml2YS5jb20iLCJjb250YWN0Tm8iOiIwMTIzNDU2Nzg5IiwiYXV0aFR5cGUiOiJudWxsIiwicGFyZW50SWQiOiJudWxsIiwibGFuZ3VhZ2UiOiJudWxsIiwiY3VycmVuY3kiOiJudWxsIiwiYWN0aXZhdGlvbkR0IjoibnVsbCIsImV4cGlyeUR0IjoibnVsbCIsImRlbGV0ZWRBdCI6Im51bGwiLCJwZXJtcyI6IntcIiVcIjo3fSIsImJhbGFuY2UiOiIxMjk5IiwiY2FjaGVkIjp0cnVlLCJpYXQiOjE0NTcxMDA5MjZ9.yn2Vb3hE7BKrXntCa-pTVAS7MwsaHD1csPZMiibOhwk';

fs.readFile('/etc/jwt/shared.key', function(err, result){
  if (err) {
    console.error("error:", err);
    return;
  }
  var verified = jwt.verify(encoded, 'ssshhhh');
  //var verified = jwt.verify(encoded, result);
  console.log("verified:", verified);
});

When I try to jwt.verify(), using a hardcoded value, the program fails

     if (err) throw err;
                     ^
JsonWebTokenError: invalid signature
    at Object.JWT.verify (/home/rvnath/projects/comviva/mbs/ecp7/dev/authserver/node_modules/jsonwebtoken/index.js:219:17)
    at /home/rvnath/projects/comviva/mbs/ecp7/dev/authserver/testverify.js:11:22
    at fs.js:334:14
    at FSReqWrap.oncomplete (fs.js:95:15)

However, if I read the secret key file (instead of hardcoding) and supply to the verify function, it works correctly. Here is the output of the program in this case:

rvnath@rv ~/projects/comviva/mbs/ecp7/dev/authserver $ node testverify.js 
verified: { id: '1',
  loginId: 'root',
  userName: 'root',
  role: '0',
  status: '1',
  password: 'acb3e141d883106de2f30d46e76c09cf',
  namak: 'root',
  lastLoginTime: 'null',
  email: 'root@ecp.ecp.com',
  contactNo: '0123456789',
  authType: 'null',
  parentId: 'null',
  language: 'null',
  currency: 'null',
  activationDt: 'null',
  expiryDt: 'null',
  deletedAt: 'null',
  perms: '{"%":7}',
  balance: '1299',
  cached: true,
  iat: 1457100926 }

My secret file is a simple text file, shown below:

rvnath@rv ~ $ cat /etc/jwt/shared.key 
ssshhhh
rvnath@rv ~ $ 

In summary, I am trying to decode by using the same secret key as stored in the file /etc/jwt/shared.key, but it fails when the key value is hardcoded in the program. What am I doing wrong here?

Edit The jwt is being generated by my server app, by reading the secret from the same file:

/** Creates a signed JSON WEB TOKEN **/
function createJWT(user) {
  return fs.readFileAsync('/etc/jwt/shared.key').then(function(cert){
    var secret = cert.toString();
    console.log("shared secret:", secret);
    var token = jwt.sign(user, secret);
    //console.log("token verification:",jwt.verify(token, cert));
    return token;
  });
}

Solution

  • That was a silly trivial issue, but took a lot of time to find out. When the secret was read from a file, it was appending an LF (linefeed) char to the string. So, when the same secret was hard-coded, it was without the LF. That explains the difference.