在 jwt.io 中总是得到无效的签名

Posted

技术标签:

【中文标题】在 jwt.io 中总是得到无效的签名【英文标题】:Always getting invalid signature in jwt.io 【发布时间】:2018-11-19 08:23:06 【问题描述】:

当我在 jwt.io 中输入生成的令牌时,我总是得到无效的签名 这是我制作令牌的代码

const secret = 'secret';
const token = jwt.sign(
    username: user.username,
    userID: user._id
  ,
  secret, 
    expiresIn: "1hr"
  
);

我做错了什么?

我正在使用 jsonwebtoken 包。 https://github.com/auth0/node-jsonwebtoken

【问题讨论】:

你为 jwt 使用了哪个包? 我正在使用 jsonwebtoken 包。 github.com/auth0/node-jsonwebtoken 【参考方案1】:

如果您使用的是jsonwebtoken lib,我尝试并能够创建令牌并进行验证。如果您仍然遇到问题,请查看代码并在 cmets 中告诉我。

var jwt = require('jsonwebtoken')

const secret = 'secret';
const token = jwt.sign(
        username: "",
        userID: 1
    ,
    secret, 
        expiresIn: "1hr"
    ,
    function(err, token) 
        if (err) 
            console.log(err);
         else 
            console.log(token);
        
    );

这是 jwt.io 的链接,我在其中输入了您使用的密码,上面写着已验证。

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IiIsInVzZXJJRCI6MSwiaWF0IjoxNTI4NTUyMDYyLCJleHAiOjE1Mjg1NTU2NjJ9.raL79zTGONyXgr9vuXzAyMflHJ0JqPYTXsy9KwmlXhA

【讨论】:

其实点击链接签名无效。但是,我可以使它与 npm 包一起使用。也许 jwt.io 以某种方式损坏了? @SteffenT 点击那里的复选框 迟到了,但网站会在您更改密码时更新您粘贴的 JWT。因此,您必须先粘贴秘密,然后粘贴 JWT。 @Wickramaranga 是正确的,但人们经常以错误的方式使用 jwt.io,没有注意到更新的签名,只是认为他们验证了令牌。我在my answer here中描述了正确的用法【参考方案2】:

TL_DR:

https://example.com/.well-known/jwks返回的JSON中的keys数组中提取第一个key,粘贴到jwt.io页面VERIFY SIGNATURE部分的第一个文本框中。当然,example.com 是您托管 OpenIddict 身份验证服务器的域。也可以是 https://example.com/my/auth/server/ 之类的东西。

整个故事:

当您将 JWT 粘贴到 jwt.io 中时,它会执行以下操作:

    解码令牌,并在右侧显示标头和有效负载 尝试验证签名

如果步骤 1. 未能解码有效负载,那是因为令牌已编码。要解决此问题,请修改 OpeIddict 配置,添加 .DisableAccessTokenEncryption();

第 2 步,签名验证,通过从 PAYLOAD 部分获取颁发者 iss 字段来完成:

并使用它作为基础 URI 来调用 /.well-known/openid-configuration,其中包括 JWKS uri,它看起来像 "jwks_uri": "https://example.com/.well-known/jwks"

jwt.io 可能无法获取此数据,例如:

如果您在 https://localhost 中进行测试,这无法通过 Internet 访问,就像本示例中的 https://localhost:5001 一样 因为请求被任何其他原因(未知域、防火墙...)拒绝

如果是这种情况,有一个解决问题的选项:将适当的字符串粘贴到VERIFY SIGNATURE部分的上部文本框中,其中有这个占位符:

SPKI、PKCS #1、X.509 证书或 JWK 字符串格式的公钥。

那里的正确字符串是什么?如果您考虑到 2 个细节,这很容易:

    您可以从上述https://example.com/.well-known/jwks 端点获取包含此信息的 JSON 返回的信息是 JWKS 字符串,但需要 JWK。

因此,调用 enpoint,获取如下所示的 JWKS:


  "keys": [
    
      "kid": "2727AC6EB83977...",
      "use": "sig",
      "kty": "RSA",
      "alg": "RS256",
      "e": "AQAB",
      "n": "6tSSW3rz53Xj3w...",
      "x5t": "Jyesbrg5d_2M...",
      "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
      ]
    
  ]

并提取 JWK,它只是 "keys" 数组中的第一个条目,即


  "kid": "2727AC6EB83977...",
  "use": "sig",
  "kty": "RSA",
  "alg": "RS256",
  "e": "AQAB",
  "n": "6tSSW3rz53Xj3w...",
  "x5t": "Jyesbrg5d_2M...",
  "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
   ]

将此值粘贴到文本框中,您将收到蓝色的“签名已验证”消息,如您在第一个快照的底部所见。

注意:根据配置(AddEphemeralSigningKey()AddDevelopmentSigningCertificate() 等),JWKS 键可以具有或多或少的属性,但无论如何它应该可以工作。

【讨论】:

【参考方案3】:

我遇到了同样的问题。单击"Verify Signature" panel. 中的“秘密base64 编码”复选框后,我对其进行了修复或验证

【讨论】:

否,通过单击“秘密 base64 编码”复选框,您不验证令牌。在您的屏幕截图中,甚至没有粘贴到输入字段的秘密。单击复选框只会重新计算签名,然后自动验证。请阅读my answer here 了解实际发生的情况以及如何正确使用 jwt.io。【参考方案4】:

我也遇到过类似的问题,后来发现是我用错了秘钥

确保您使用的是正确的密钥

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于在 jwt.io 中总是得到无效的签名的主要内容,如果未能解决你的问题,请参考以下文章

.NET 库中的 JWT 无效签名

使用刷新令牌时 Spring Boot JWT 令牌无效签名

.NET:RS256 签名的 JWT 中的签名无效

PHP 中的自定义 JWT 一直说签名无效

为啥我的来自 Amazon Cognito 的 JWT 令牌具有无效签名?

签署令牌如何工作? (无效签名错误)