Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS Crypto RS-SHA256 and JWT Bearer

In implementing an oauth2 stack utilizing passport and oauth2orize, in this case the issue is specifically in utilizing the oauth2orize jwt bearer. The oauth2orize jwt bearer is great in getting everything going, however it has the RSA SHA pieces marked as to do.

In attempting to put in the pieces for the RSA SHA encryption handling, I cannot get the signature to verify as verifier.verify always seems to return false. If anyone has cleared this hurdle, a little help would be super.

What I've done: Created the private / public keys:

openssl genrsa -out private.pem 1024
//extract public key
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

now the data to sign:

{"alg":"RS256","typ":"JWT"}{"iss": "myclient"}

I've tried multiple ways as to how to sign this, too many to list here, but my understanding of the correct signature is to sign the bas64 encoding of these items, so i ran base64 on {"alg":"RS256","typ":"JWT"} and base64 on {"iss": "myclient"} then ran base64 on those encodings. So the result is: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 eyJpc3MiOiAibXljbGllbnQifQ then encode:

{eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9}.{eyJpc3MiOiAibXljbGllbnQifQ}

which gives me: e2V5SmhiR2NpT2lKU1V6STFOaUlzSW5SNWNDSTZJa3BYVkNKOX0ue2V5SnBjM01pT2lBaWJYbGpiR2xsYm5RaWZRfQ

At this point I sign the above base64 by doing:

openssl sha -sha256 -sign priv.pem < signThis > signedData

Then I run base64 on that to get the data to pass into the signature part of the assertion. I then pass in the object:

{
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion":  "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiAibXljbGllbnQifQ.signedData"
}

now in the code base I have:

var crypto = require('crypto')
   , fs = require('fs')
   , pub = fs.readFileSync('/path/to/pub.pem')
   , verifier = crypto.createVerify("RSA-SHA256");

verifier.update(JSON.stringify(data));

var result = verifier.verify(pub, signature, 'base64');
console.log('vf: ', result);

however, result is always false.

I do properly receive the data, the signature variable in the code is a match for what I'm passing in, I just always receive false and have exhausted all options I can think of on how to tweak this to get verifier.verify to return true. Thank you for the time and help!

like image 267
purdytx Avatar asked Nov 17 '25 22:11

purdytx


1 Answers

I am not sure if this is exactly what you were looking for, but this will successfully create a JWT in a google api fashion using jwt-simple (which uses crypto and such):

var fs       = require('fs')
  , jwt      = require('jwt-simple')
  , keypath  = '/path/to/your.pem'
  , secret   = fs.readFileSync( keypath, { encoding: 'ascii' })
  , now      = Date.now()
  , payload  = {
        scope: 'https://www.googleapis.com/auth/<service>',
        iss  : '<iss_id>@developer.gserviceaccount.com',
        aud  : 'https://accounts.google.com/o/oauth2/token',
        iat  : now,
        exp  : now+3600
    }
  , token    = jwt.encode( payload, secret, 'RS256' )
  , decoded  = jwt.decode( token, secret, 'RS256' );

console.log( token );
console.log( decoded );
like image 91
jiminikiz Avatar answered Nov 19 '25 13:11

jiminikiz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!