NodeJS加密RS-SHA256和JWT承载

时间:2013-12-26 20:25:01

标签: node.js cryptography oauth-2.0 jwt

在使用passport和oauth2orize实现oauth2堆栈时,在这种情况下,问题特别在于使用oauth2orize jwt承载。 oauth2orize jwt持有者可以很好地完成所有工作,但它有标记为RSA SHA的部分。

在尝试放入用于RSA SHA加密处理的部分时,我无法获得签名以验证为verifier.verify似乎总是返回false。如果有人已经清除了这个障碍,那么一点点的帮助将是超级的。

我做了什么: 创建了私钥/公钥:

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

现在要签署的数据:

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

我已经尝试过多种方式来签署这个,这里列出的太多了,但我对正确签名的理解是签署这些项目的bas64编码,所以我在{“alg”上运行了base64:“ RS256“,”typ“:”JWT“}和{”iss“上的base64:”myclient“}然后在这些编码上运行base64。结果是: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 eyJpc3MiOiAibXljbGllbnQifQ 然后编码:

{eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9}.{eyJpc3MiOiAibXljbGllbnQifQ}

给了我: e2V5SmhiR2NpT2lKU1V6STFOaUlzSW5SNWNDSTZJa3BYVkNKOX0ue2V5SnBjM01pT2lBaWJYbGpiR2xsYm5RaWZRfQ

此时我通过执行以下操作签署上述base64:

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

然后我在其上运行base64以使数据传递到断言的签名部分。 然后我传入了对象:

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

现在在我的代码库中:

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);

然而,结果总是错误的。

我正确地接收数据,代码中的签名变量与我传入的内容相匹配,我总是收到错误并且已经用尽了我可以想到的关于如何调整这个以获得验证器的所有选项。验证返回true。感谢您的时间和帮助!

2 个答案:

答案 0 :(得分:1)

我不确定这是否正是您所期待的,但这将使用jwt-simple(使用加密等)以谷歌API方式成功创建JWT:

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 );

答案 1 :(得分:1)

我认为此代码示例完全不安全。如果你查看最新的JWT代码,它就不会在你的解码调用中使用这个秘密。

https://github.com/hokaccha/node-jwt-simple/blob/master/lib/jwt.js

它基本上只是对第二段进行解码并返回它,这意味着任何人都可以更改该值并且未经验证。