【问题标题】:Verifying AWS Cognito JWT IDToken against a JWK Set with njwt使用 njwt 针对 JWK 集验证 AWS Cognito JWT IDToken
【发布时间】:2017-09-01 19:12:11
【问题描述】:

我正在尝试弄清楚如何验证从 AWS Cognito Identity authenticateUser 调用获得的用户 IDToken。

按照此处找到的步骤:https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-identity-user-pools-using-id-and-access-tokens-in-web-api 我能够到达拥有用户 ID 令牌并且已解码标题和正文的地步。

给定一个 IDToken,这就是我的标题和正文的样子:

标题:

{
    typ: 'JWT',
    alg: 'RS256',
    kid: '...'
}

正文:

{
    sub: 'abcd...',
    aud: 'abcdefg...',
    email_verified: true,
    token_use: 'id',
    auth_time: 1491491773,
    iss: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-...',
    'cognito:username': 'username',
    exp: 1491495373,
    iat: 1491491773,
    email: 'user@email.com'
}

那么IDToken的第三部分就是签名:

'T6tjQ...' // big long encoded string

我坚持的部分实际上是根据我的签名密钥验证签名。我似乎无法让这部分工作。现在我正在尝试使用此处找到的njwt 节点模块:https://www.npmjs.com/package/njwt。

给定 IDToken 作为 3 部分 . 分隔的 base64 编码字符串,以及 secretKey 作为以下 Javascript 对象:

{
    alg: 'RS256',
    e: '...',
    kid: '...', // matches kid of IDToken
    kty: 'RSA',
    n: 'abcdefg...', // Appears to be some big long encoded string
    use: 'sig'
}

这是我在 njwt 节点模块上尝试过的:

njwt.verify(IDToken, secretKey, 'RS256', function(err, verifiedJwt)
{
    if (err)
    {
        console.log(err);
    }
    else
    {
        console.log('Verified');
    }
});

当我以这种方式尝试时,我得到:

TypeError: Not a buffer
    at Verify.verify (crypto.js:426:24)
    at .../node_modules/njwt/index.js:406:10
    at Verifier.defaultKeyResolver (.../node_modules/njwt/index.js:72:10)
    at Verifier.verify (.../node_modules/njwt/index.js:375:15)
    at Object.jwtLib.verify (.../node_modules/njwt/index.js:457:21)
    at repl:1:6
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)

所以我想也许我需要像这样传递secretKey.n 而不是secretKey:

njwt.verify(IDToken, secretKey.n, 'RS256', function(err, verifiedJwt)
{
    if (err)
    {
        console.log(err);
    }
    else
    {
        console.log('Verified');
    }
});

当我以这种方式尝试时,我得到:

139980866705216:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:696:Expecting: CERTIFICATE

跟着我的console.log(err);:

{ [JwtParseError: Signature verification failed]
  name: 'JwtParseError',
  userMessage: 'Signature verification failed',
  message: 'Signature verification failed',
  jwtString: 'abcdefg...',
  parsedHeader: {
    typ: 'JWT',
    alg: 'RS256',
    kid: '...'
  },
  parsedBody: {
    sub: 'abcd...',
    aud: 'abcdefg...',
    email_verified: true,
    token_use: 'id',
    auth_time: 1491491773,
    iss: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-...',
    'cognito:username': 'username',
    exp: 1491495373,
    iat: 1491491773,
    email: 'user@email.com'
  },
  innerError: undefined }

我应该如何传递secretKey? secretKey 应该是什么,它应该是什么样子?老实说,我什至不确定njwt.verify 在期待什么。

【问题讨论】:

    标签: node.js cryptography jwt aws-cognito jwk


    【解决方案1】:

    问题似乎在于njwt.verify 需要一个公共 RSA 密钥。我必须将我的 JWK Set 对象转换为公共 RSA 密钥。我通过使用jwk-to-pem 节点模块做到了这一点。

    鉴于问题中的相同secretKey:

    var jwkToPem = require('jwk-to-pem');
    
    var pem = jwkToPem(secretKey);
    
    njwt.verify(IDToken, pem, 'RS256', function(err, verifiedJwt)
    {
        if (err)
        {
            console.log(err);
        }
        else
        {
            console.log('Verified');
        }
    });
    

    成功了!

    【讨论】:

      猜你喜欢
      • 2018-03-07
      • 2021-05-09
      • 2021-10-03
      • 2022-01-26
      • 2020-07-13
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      相关资源
      最近更新 更多