如何在没有 x5c 的情况下从 jwks 验证 JWT 的签名 [英] How to validate signature of JWT from jwks without x5c

查看:42
本文介绍了如何在没有 x5c 的情况下从 jwks 验证 JWT 的签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 JWT 安全令牌,需要通过 jwks 端点进行验证.jwks 中的数据看起来像:

I have a JWT security token which I need to verify via jwks endpoint. Data in jwks looks like:

{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "alg": "RS256",
      "n": "......",
      "kid": "2132132-b1e6-47e7-a30f-1831942f74bd"
    },
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "alg": "RS256",
      "n": "......",
      "kid": "tsp-app-a"
    },
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "alg": "RS256",
      "n": ".....",
      "kid": "tsp-app-b"
    }
  ]
}

我尝试了一个第三方 api,但它看起来依赖于 x5c 密钥,而我的案例中不存在该密钥.

I have tried one third party api but it looks like it is dependent on x5c key which isn't present in my case.

我的代码是:

public static bool Validate(JwtSecurityToken jsonToken)
        {
            bool result = false;
            try
            {
                var headers = Jose.JWT.Headers<JWTHeader>(jsonToken.RawData);
                var payload = Jose.JWT.Payload<JWTPayload>(jsonToken.RawData);

                string jwk = "";
                using (HttpClient cli = new HttpClient())
                {
                    jwk = cli.GetStringAsync(MyclientUrlforWellknownjson).Result;
                }

                var jwkinfo = JsonSerializer.Deserialize<JWKS>(jwk);
                //Find right key. Match kid and alg,  (To be changed later. It is possible that there are multiple x5c elements in key)
                var jwkkey = (from item in jwkinfo.keys where item.kid == headers.kid && item.alg == headers.alg select item).SingleOrDefault();

                //If key was found then load its public key
                System.Security.Cryptography.X509Certificates.X509Certificate2 cert = null;
                if (jwkkey != null)
                {
                    //Get public key from well known information
                    byte[] key = System.Text.Encoding.ASCII.GetBytes(jwkkey.x5c[0]); //??todo 
                    //Create cert                   
                    cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(key);
                }

                var o = Jose.JWT.Decode(jsonToken.RawData, cert.PublicKey.Key);


            }
            catch (Exception ex)
            {

            }
            return result;
        }

如何在没有 x5c 的情况下通过 jwks 验证 JWT?

How can I validate a JWT via jwks without x5c?

推荐答案

使用 x5c 只是一种方法,但您也可以使用参数 e 检索公钥(公共指数)和 n(模数),这也记录在 jose-jwt github 页面:

Using x5c is just one way, but you can also retrieve the public key with the parameters e (public exponent) and n (modulus), which is also documented on the jose-jwt github page:

//If kid was found then load public key
if (jwkkey != null)
{
    RSACryptoServiceProvider key = new RSACryptoServiceProvider();
    key.ImportParameters(new RSAParameters
    {
        Modulus = Base64Url.Decode(jwkkey.n),
        Exponent = Base64Url.Decode(jwkkey.e)
    });
}

// get the public key in PEM format, e.g. to use it on jwt.io
var pubkey = Convert.ToBase64String(key.ExportSubjectPublicKeyInfo());
const string pemHeader = "-----BEGIN PUBLIC KEY-----";
const string pemFooter = "-----END PUBLIC KEY-----";
var publicKeyPem = pemHeader + Environment.NewLine + pubkey + Environment.NewLine + pemFooter;

var o = Jose.JWT.Decode(jsonToken.RawData, key);

您还可以再次以 PEM 格式导出公钥,如上面的代码所示,如​​下所示:

You can also export the public key in PEM format again as shown in the code above, which will look like this:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIdJV4qWKyt3wkS66yBG5Ii9ew+eofuPU49TjlRIU5Iu5jX2mRMoHdcI7V78iKYSQHKYxz17cqzQyERxKnEiDgy/gwouStRgvPdm3H4rq//7p0t15SunsG2T1rEVf0sZEDnQ5qRkm7iqs6ZG1NqqIUtnOTd1Pd1MhbEqeENFtaPHvN37eZL82WmsQlJviFH4I9iZQVR/QT4GREQlRro8IjJTaloUyeDQTOQ+4ll1+4+g/ug2tZ+s9xleLzl5L9ZKSVJFhtMLn8WGaVldagarwa7kMLfuiVe8B5Lr7poQa4NCAR54ECPWoOHrABdPZKrkkxjVypTXUzL5cPzmzFC2xwIDAQAB
-----END PUBLIC KEY-----

然后使用该密钥在 https://jwt.io

(在 @Topaco 的提示)

这篇关于如何在没有 x5c 的情况下从 jwks 验证 JWT 的签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆