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



在从网络上清理了一些零碎的东西并试图让它发挥作用后,我放弃了。

现在是:

我有一个签名加密为RSA-SHA256的OpenID令牌。我已经使用JWT.net库尝试了以下代码

这是代币:

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;
}

我得到以下错误:

根据验证过程,签名无效。

现在,我真的不知道这个模数和指数字符串是什么。我只是从别人举的例子中复制了它们,所以我不知道这是否与我的问题有关。

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

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

模和指数是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密钥库(,则可以传递一个方法,该方法将使用JWT令牌中指定的密钥名称进行调用。

最新更新