验证Auth0 JWT会引发无效的算法

Roc*_*CTZ 7 oauth node.js jwt auth0

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

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1rVkdOa1l5T1VaQ1JqTkRSVE5EUmtNeU5rVkROMEUyUTBVMFJrVXdPVEZEUkVVNU5UQXpOZyJ9.eyJpc3MiOiJodHRwczovL3RvdGFsY29tbW56LmF1LmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwMzI5NzA4OTYyMTk5NjUwMjY2MiIsImF1ZCI6ImxTWUtXMUZZdENkMWJLQmdXRWN0MWpCbmtDU3R2dW5SIiwiaWF0IjoxNTA5ODYyMTI1LCJleHAiOjE1MTAyMjIxMjV9.kjmckPxLJ4H9R11XiBBxSNZEvQFVEIgAY_jj2LBy4sEJozBB8ujGE7sq9vEIjMms-Lv2q9WzFQPrqcxyBcYC4Je4QojMgvqLDCodtpot0QUle8QfGmonc1vZYIZyX-wqyOXtRqhoZVEKTeLhm9Le2CV4_a3BwgjkE1LjcDx01GZfsnaId8mh10kGk-DBmr5aVc8MxglLCq5Uk8Zbl2vDc__UMDgx1eQPQg-zve4fUf8zHcxizypYTnF_v0dEAT00L2j5J41SFYdWvP6ReQ3vhVYew2o9iM6u1s75HE-xW8s4pzV4BZAQtgfgIeCd6aVGZs76bcnQXBLej1B7zaPBvA
Run Code Online (Sandbox Code Playgroud)

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

我将签名证书下载为a .pem并且我成功使用它来验证令牌,如下所示:

var cert = fs.readFileSync('certificate.pem');
jwt.verify(token, cert, {algorithm: 'RS256'}, (err, decoded) => {
  console.log(err)
  console.log(decoded)
});
Run Code Online (Sandbox Code Playgroud)

我想要做的是它不起作用是使用秘密验证令牌(在Auth0客户端设置中称为客户端密钥,并且是一个字符串).

jwt.verify(token, MYSECRET, {algorithm: 'RS256'}, (err, decoded) => {
  console.log(err)
  console.log(decoded)
});
Run Code Online (Sandbox Code Playgroud)

此代码始终抛出错误:

{ 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' }
Run Code Online (Sandbox Code Playgroud)

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

Mik*_*kaS 6

如果您使用的只有一个密钥,然后使用RS256将无法正常工作,因为它是基于私有/公共密钥对。仅使用密钥通常表示H256。在我的回答中,我假设您所说MYSECRET的只是的内容certificate.pem

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

-----BEGIN RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)

-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)

PUBLIC而不是PRIVATE

您可以在源代码中看到它。错误消息中提到的行包含:

if (!~options.algorithms.indexOf(header.alg)) {
  return done(new JsonWebTokenError('invalid algorithm'));
}
Run Code Online (Sandbox Code Playgroud)

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' ];

}
Run Code Online (Sandbox Code Playgroud)

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

我以前没有在JWT中使用RS256,但是我在ssh中使用了RS256,我知道它对拥有标头非常敏感。该字符串必须采用完全正确的格式。


JBa*_*lin 6

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

jwt.verify(token, MYSECRET, { algorithms: ['RS256'] });
Run Code Online (Sandbox Code Playgroud)