使用 ASP.NET Core 5 验证 JWT 加密令牌

Verifying a JWT encrypted token with ASP.NET Core 5

在从网上搜集一些零碎的东西并尝试让它工作后,我放弃了。

这里是:

我有一个带有 RSA-SHA256 签名加密的 OpenID 令牌。 我使用 JWT.net library

尝试了以下代码

这是令牌:

eyJhbGciOiJSUzI1NiIsImtpZCI6Ii11Zm0wSEVuMVpSbktHV2ZmQUttd0h0bEV4RSJ9.eyJzdWIiOiJhbG9uIiwiYXVkIjoiMTIzNDUiLCJqdGkiOiJMeVlDeGo4MzNEbHV3V2h0Q0s4OXZmIiwiaXNzIjoiaHR0cHM6Ly8xMC4xNDYuMzIuMTY0OjkwMzEiLCJpYXQiOjE2NDUwMjU4NjYsImV4cCI6MTY0NTAyNjE2NiwiYXV0aF90aW1lIjoxNjQ1MDI1ODY2fQ.KtS1WR3A61uSalUfrwbORx8AcYtsqudj9KlzFmf98W8PbwpSUu0axJmDYjHnH35ltYDjiZgX06RMKOSWQILt2O_4P2T1DtKUz0UOLjW04rpbz-pyOuw6sxQMHOQNUsUt_effojsBB6ISA6ejs-DKx652_M0JYMdZ_GnN2CODJdpZQIYI7xTgaOVrJjjzcxeczcMkGMTryS0qN8U4Pjy9Y4TAVTgSDw3Ca-dw-abwI4oY1aZILDEHglcCVcSMC5Vu6uO1BiLTD7Gc7wbMUi05OPxDrv4xumXVYVDpXhM4kENnoK3_gmGZMQ3SvFWAcFahwR-lyb8gisK8gZZ19PG-Iw

这是我试过的最新代码:

 string modulus = "w7Zdfmece8iaB0kiTY8pCtiBtzbptJmP28nSWwtdjRu0f2GFpajvWE4VhfJAjEsOcwYzay7XGN0b-X84BfC8hmCTOj2b2eHT7NsZegFPKRUQzJ9wW8ipn_aDJWMGDuB1XyqT1E7DYqjUCEOD1b4FLpy_xPn6oV_TYOfQ9fZdbE5HGxJUzekuGcOKqOQ8M7wfYHhHHLxGpQVgL0apWuP2gDDOdTtpuld4D2LK1MZK99s9gaSjRHE8JDb1Z4IGhEcEyzkxswVdPndUWzfvWBBWXWxtSUvQGBRkuy1BHOa4sP6FKjWEeeF7gm7UMs2Nm2QUgNZw6xvEDGaLk4KASdIxRQ";
 string exponent = "AQAB";

 try
 {
     IDictionary<string, object> claims = Decode(token, modulus, exponent);
}
catch (SignatureVerificationException ex)
{
     // signature invalid, handle it here
     return false;
}
return true;

private static IDictionary<string, object> Decode(string token, string modulus, string exponent)
{
    var urlEncoder = new JwtBase64UrlEncoder();

    var rsaKey = RSA.Create();
    rsaKey.ImportParameters(new RSAParameters()
        {
            Modulus = urlEncoder.Decode(modulus),
            Exponent = urlEncoder.Decode(exponent)
        });

    var claims = new JwtBuilder()
            .WithAlgorithm(new RS256Algorithm(rsaKey))
            .MustVerifySignature()
            .Decode<IDictionary<string, object>>(token);

    return claims;
}

我收到以下错误:

The signature is invalid according to the validation procedure.

现在,我真的不知道这个模数和指数字符串是什么。我只是从别人给的例子里抄来的,不知道是不是和我的问题有关

此代码也没有使用我的密钥。

我没有自己生成令牌。第三方授权服务器正在生成它。

模数和指数是 RSA 密钥的一部分,它基本上是尝试从已知值重新创建 RSA 密钥(我不知道是否像您那样工作)。

无论如何,您可以使用 System.IdentityModel.Tokens.Jwt 包中的 JwtSecurityTokenHandler 代替。然后您所要做的就是直接传递相关参数(实际的 RSA 密钥),如果成功,它将验证并返回有效令牌。像这样:

SecurityToken validatedToken;
ClaimsPrincipal principal = validator.ValidateToken(jwtToken, GetValidationParameters(), out validatedToken);

验证参数是这样的:

private TokenValidationParameters GetValidationParameters()
        {
            return new TokenValidationParameters
            {
                IssuerSigningKey = GetRSAKey(),
                ValidIssuer = jwtConfig.Issuer,
                ValidAudience = jwtConfig.Audience,
                ValidateIssuerSigningKey = true,
                IssuerSigningKeyResolver = GetMethodToResolveExternalKey(),
                ValidateIssuer = true,
                ValidateAudience = false,
                ValidateLifetime = true,
            };
        }

请注意,签名密钥和签名密钥解析器是不同的技术。如果您在本地拥有密钥,您可以直接传递密钥,但如果您需要在其他地方查找它(例如 Azure Key Vault),您可以传递一个方法,该方法将使用 JWT 令牌中指定的密钥名称进行调用。