当前位置: 首页 > 知识库问答 >
问题:

验证JWT签名时的异常

益智明
2023-03-14

我正在尝试为我的组织实施OpenID Connect规范。我正在一个测试依赖方应用程序中使用微软的OpenID Connect的OWIN实现来验证我的协议实现。

我公开了以下元数据文档:

{
  "issuer": "https://acs.contoso.com/",
  "authorization_endpoint": "http://localhost:53615/oauth2/auth",
  "token_endpoint": "http://localhost:53615/oauth2/token",
  "userinfo_endpoint": "http://localhost:53615/connect/userinfo",
  "jwks_uri": "http://localhost:53615/connect/keys",
  "ui_locales_supported": [
    "en-GB"
  ]
}

签名密钥公开为以下文档:

{
  "keys": [
    {
      "n": "xpXxl3M-YkZlzQJdArO1TfOGT2no-UL4dbZ7WuSCNIsSfyGDaqUXjMMHNyq9yD3vp-NCyk8kmn7d5XqHufnceXJM8q4xTrhN3lvywdBSbR-dwXsA-B-MJVgfiK0d_z-mxP9ew2Hj9-KkWbWCzsswlWp3gZ4mB4RGutB1IRSzXVIbvZ-MtKUb6XUDU4LDb_c1xCEXWZxhR-o1a1dLfObH2hHJ-w5y6odGlKtOFx4i4h0u7-Oj5R6k5b2YXEHM0IuYeN0u0sQvrTecokntGzPrvhnKy69I7Z_az5rC5kgloh25D9lTbe4vcRU7FXlYCFYDZsT0_IkGIXRi7brOS4f1ow",
      "e": "AQAB",
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "F8A59280B3D13777CC7541B3218480984F421450"
    }
  ]
}

身份令牌是使用JwtSecurityToken类及其关联的处理程序,使用X509SigningCredentials类生成的。此代码代表令牌的构造方式,并将其作为响应数据的参数返回给调用系统。

var credentials = new X509SigningCredentials(cert); // My certificate.
var issuedTime = DateTime.UtcNow;
var expiresTime = issuedTime.AddMinutes(5);
var epoch = new DateTime(1970, 01, 01, 0, 0, 0);

var claims = new[]
{
    new Claim("sub", Guid.NewGuid().ToString()),
    new Claim("iat" Math.Floor((issuedTime - epoch).TotalSeconds).ToString()),
    new Claim("nonce", nonce), // Value from client
}

var token = new JwtSecurityToken(
    "https://acs.contoso.com",
    client_id, // Value from client
    claims,
    new Lifetime(issuedTime, expiresTime),
    credentials);

var handler = new JwtSecurityTokenHandler();
parameters.Add("id_token", handler.WriteToken(token)); // Outgoing parameters.

当我试图将签名的令牌传递回依赖方应用程序时,OWIN中间件接受POST并尝试验证令牌的签名。执行此操作时,会引发以下异常:

SecurityTokenSignatureKeyNotFoundException:IDX10500:签名验证失败。无法解析SecurityKeyIdentifier:“SecurityKeyIdentifier(IsReadOnly=False,Count=1,子句[0]=X509ThumbprintKeyIdentifierClause(Hash=0xF8A59280B3D13777CC7541B3218480984F421450)),令牌:“{”typ:“JWT”,“alg:“RS256”,“x5t:”-KWSGLPRN3FMDUGZYSAME9CFFA”}。{“iss”:https://test.accesscontrol.net/“,”aud:”测试“,”nbf:”1404917162“,”exp:”1404917462“,”sub:”60eb55ec-0699-4068-bfa6-41666fc2b2e9“,”iat:”14049171622.参考参考参考资料:参考参考参考资料:参考参考参考资料:参考参考数据:参考数据:参考数据:参考数据:参考数据:参考数据。参考数据:参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。参考数据。2.参考数据。2。2.参考数据。2。2.参考数据。2.参考数据。2。2.参考数据。2。2.参考数据。2。2.参考数据。2。2。2。2.参考数据。2。2。2。2。2。2。2。2。ZZDZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZYYYYYYYYYYYYYYYYY2。2。2。2。2。2。2。2 XXXXXXXXXXXXDQFQ70N8QEYIR8VTR6OQQNO6UQXQX4RXUS6ZKFK9LIV3N9NHCS97WJP2JFEFJYESYTRMWCNWSL7VKM2JXQFWKOQTNOGP-BA04TTI6JVRJHOQXH43EKJ9VNUBUZDD-T8CADMNBVH0NWPIB8KWBW5V8SA0AQUXMJYBLC2W3X13QNYVJ4FA7N7N7N7C1IT0KEB-VKFKF8VKKF7N7N7VKF7N7N7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V7V。

该组件仍然是预发布的,所以这可能是实现中的一个缺陷,但是我想假设这是我的错误,直到排除所有可能性。

我做了什么明显错误的事情,或者我应该做些什么来准确理解签名无法验证的原因?

共有2个答案

锺离声
2023-03-14

我遇到过这个异常。在我的例子中,我们的应用程序正在缓存来自Azure环境的签名密钥,因为它们不经常更改,但是没有刷新密钥的机制。由于签名密钥最终会轮换,我们收到了有效的JWT,但是有一个旧的签名密钥列表,在这种情况下,没有一个能够验证JWT签名。

陆文博
2023-03-14

问题位于异常消息中:

子句[0]=X509ThumbprintKeyIdentifierClause(散列=0xF8A59280B3D13777CC7541B3218480984F421450)

令牌由X.509证书的默认密钥标识符子句签名:其指纹。元数据只公开RSA参数和名称标识符。当客户端检索元数据时,它会使用此信息设置RSA密钥,而不是X.509指纹。

要更正此错误,必须更改签名凭据以包含正确的名称标识符:

var credentials = new X509CertificateCredentials(
    cert,
    new SecurityKeyIdentifier(
        new NamedKeySecurityKeyIdentifierClause(
            "kid",
            "F8A59280B3D13777CC7541B3218480984F421450")));

这包括签名中的预期标识符,并且签名被成功验证。

 类似资料:
  • 我目前正在使用Vapor开发Swift后端。我的iOS客户端使用新的iOS 13功能“使用Apple登录”。当用户登录时,我会得到一个身份令牌(访问令牌),这是一个由Apple签名的有效JWT令牌。这将在所有正在进行的通信中发送到服务器,以验证服务器提供的某些路由。 在服务器上,我想通过验证令牌签名来验证发送的令牌是否确实由Apple签名,并且不是由某些恶意用户专门创建的。Apple提供了一个HT

  • 我正在制作一个javascript客户端,它使用JWT令牌连接到Api。在服务器端没有问题,我可以创建令牌对其进行签名,然后验证签名,从而确保没有人篡改令牌。 但我如何在客户端做到这一点。我可以解码JWT令牌并查看头、负载和签名。但是如何在客户端验证签名?是否有用于此的库,如何将公钥传输到客户端? 如果我不验证签名,我怎么知道令牌没有被篡改?

  • 使用库"firebase_id_token"验证ruby on rails中的Firebase id令牌。 一旦我用google_sign_in库从前端获得有效令牌并发送到后端,它总是提示“JWT::VerificationError(签名验证引发)”。尽管我已经检查了jwt.io,在那里我可以看到有效载荷和报头的信息,但无法验证签名。 firebase_id_token.rb 另外,我检查了密钥

  • 我有一个由keyCloack生成的JWT,RS256,类似这样的东西 样本: 我需要使用KeyClock证书解码和验证此令牌。 我可以通过api获得KeyClock证书。 在响应中,我有x5c字段。 我可以验证这个jwthttps://jwt.io/如果我把x5c部件放在----证书----标签内 如何在Java中验证同样的事情? 我尝试了几件事,但都失败了。

  • 我需要使用jwt验证令牌。木卫一 为此,我有一个令牌(许可证)eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRJZCI6MjcwMzYwLCJwYWNrYWdlc............" 和json(证书) “密钥”:[{“kid”:“1”,“e”:“AQAB”,“kty”:“RSA”,“alg”:“RS256”,“n”:“rXYc2Ehtb42R

  • 这就是我面临的问题, https://play.golang.org/p/Pq8xHAERD57 如果运行上述代码,第一个令牌JWKS对不会验证签名,但第二个会验证!但两者都在jwt中验证签名。木卫一。有什么办法可以用一个Golang图书馆来验证它吗? 奇怪的是如果你拿了失败的代币?我调试后发现函数func VerifyPKCS1v15(pub*PublicKey,hash crypto.hash