验证 Auth0 JWT 抛出无效算法

Posted

技术标签:

【中文标题】验证 Auth0 JWT 抛出无效算法【英文标题】:Verifying Auth0 JWT throws invalid algorigthm 【发布时间】:2018-04-17 13:25:27 【问题描述】:

我已经创建了一个 Auth0 客户端,我正在登录并收到这个令牌:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1rVkdOa1l5T1VaQ1JqTkRSVE5EUmtNeU5rVkROMEUyUTBVMFJrVXdPVEZEUkVVNU5UQXpOZyJ9.eyJpc3MiOiJodHRwczovL3RvdGFsY29tbW56LmF1LmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwMzI5NzA4OTYyMTk5NjUwMjY2MiIsImF1ZCI6ImxTWUtXMUZZdENkMWJLQmdXRWN0MWpCbmtDU3R2dW5SIiwiaWF0IjoxNTA5ODYyMTI1LCJleHAiOjE1MTAyMjIxMjV9.kjmckPxLJ4H9R11XiBBxSNZEvQFVEIgAY_jj2LBy4sEJozBB8ujGE7sq9vEIjMms-Lv2q9WzFQPrqcxyBcYC4Je4QojMgvqLDCodtpot0QUle8QfGmonc1vZYIZyX-wqyOXtRqhoZVEKTeLhm9Le2CV4_a3BwgjkE1LjcDx01GZfsnaId8mh10kGk-DBmr5aVc8MxglLCq5Uk8Zbl2vDc__UMDgx1eQPQg-zve4fUf8zHcxizypYTnF_v0dEAT00L2j5J41SFYdWvP6ReQ3vhVYew2o9iM6u1s75HE-xW8s4pzV4BZAQtgfgIeCd6aVGZs76bcnQXBLej1B7zaPBvA

我现在要做的是使用jsonwebtoken 验证令牌。令牌使用 RS256 算法进行签名。

我以.pem 的形式下载了签名证书,并且我成功使用它来验证令牌,如下所示:

var cert = fs.readFileSync('certificate.pem');
jwt.verify(token, cert, algorithm: 'RS256', (err, decoded) => 
  console.log(err)
  console.log(decoded)
);

我想做但不起作用的是使用密钥(在 Auth0 客户端设置中称为 Client Secret 并且是一个字符串)验证令牌。

jwt.verify(token, MYSECRET, algorithm: 'RS256', (err, decoded) => 
  console.log(err)
  console.log(decoded)
);

这段代码总是抛出错误:

 JsonWebTokenError: invalid algorithm
    at Object.module.exports [as verify] (C:\code\aws\learn-authorizer\node_modules\jsonwebtoken\verify.js:90:17)
    at Object.<anonymous> (C:\code\aws\learn-authorizer\testme.js:25:5)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)
    at Function.Module.runMain (module.js:665:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3 name: 'JsonWebTokenError', message: 'invalid algorithm' 

我的问题是:如何使用密钥而不是使用证书文件来验证 RS256 令牌? (我也尝试创建一个使用 HS256 算法的新客户端,但我得到了同样的错误)。

【问题讨论】:

尝试更新您的 jwt 模块。 @AkshitGrover 我已经使用最新版本了 【参考方案1】:

您需要更改验证方法的第三个参数,即

algorithm: 'RS256' to ==>algorithms: 'RS256'

并确保为算法编写正确的名称,它会正常工作

【讨论】:

【参考方案2】:

您需要将允许的algorithms 指定为字符串数组,而不是algorithm 字符串。

jwt.verify(token, MYSECRET,  algorithms: ['RS256'] );

【讨论】:

【参考方案3】:

如果您使用密钥,那么使用 RS256 将不起作用,因为它基于私钥/公钥对。仅使用密钥通常表示 H256。在我的回答中,我假设您所说的 MYSECRET 只是 certificate.pem 的内容。

无论如何,我认为你的字符串必须包含

-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----

PUBLIC 而不是 PRIVATE

您可以在source 中看到这一点。您的错误消息中提到的行包含:

if (!~options.algorithms.indexOf(header.alg)) 
  return done(new JsonWebTokenError('invalid algorithm'));

options.algorithms 被定义为

if (!options.algorithms) 
  options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') ||
                       ~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ?
                        [ 'RS256','RS384','RS512','ES256','ES384','ES512' ] :
                       ~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ?
                        [ 'RS256','RS384','RS512' ] :
                        [ 'HS256','HS384','HS512' ];


如果您在开始和结束时没有 RSA 东西,它将寻找以下算法:'HS256','HS384','HS512'

我之前没有用过RS256和JWT,但是我用过ssh,而且我知道它对有header很敏感。字符串必须采用完全正确的格式。

【讨论】:

【参考方案4】:

您是否尝试将算法设置为“HS256”?

根据https://auth0.com/docs/api-auth/tutorials/verify-access-token#verify-the-signature 的 Auth0 文档

For HS256, the API's Signing Secret is used. You can find this information at your API's Settings. Note that the field is only displayed for APIs that use HS256.

For RS256, the tenant's JSON Web Key Set (JWKS) is used. Your tenant's JWKS is https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json.

【讨论】:

以上是关于验证 Auth0 JWT 抛出无效算法的主要内容,如果未能解决你的问题,请参考以下文章

带有 JWT 的 Express API 返回“未经授权:算法无效错误”

Auth0 - 验证 JWT

PHP中的Auth0 JWT令牌验证

Django + Auth0 JWT 身份验证拒绝解码

Auth0 java-jwt 库无法验证有效令牌

Angular 2 和 JWT 身份验证 (Auth0)