我使用的是NuGet包System.IdentityModel.Tokens.Jwt版本4.0.4.403061554。
我有一个验证JWT的实现,它在算法HS256中运行良好。
然而,如果我将JWT更改为使用algo HS512生成,那么我在验证过程中会收到一个错误。
System.IdentityModel.SignatureVerificationFailedException
HResult=0x80131501
Message=IDX10503: Signature validation failed. Keys tried: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey
'.
Exceptions caught:
'System.InvalidOperationException: IDX10632: SymmetricSecurityKey.GetKeyedHashAlgorithm( 'HS512' ) threw an exception.
SymmetricSecurityKey: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey'
SignatureAlgorithm: 'HS512', check to make sure the SignatureAlgorithm is supported.
我尝试过生成512位密钥,也尝试过较小的密钥,比如256位密钥(使用algo HS256的密钥(,但都不起作用。
我的实现是:
InMemorySymmetricSecurityKey signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes("secretsigningkey"));
TokenValidationParameters tokenValidationParameters = new TokenValidationParameters()
{
ValidAudiences = validAudiences,
ValidIssuers = validIssuers,
IssuerSigningKey = signingKey
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
var claimsPrincipal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
并且异常由此方法抛出tokenHandler.ValidateToken.
我如何更改我的代码以允许HS512(以及任何其他类型的JWT支持的算法(??
- 根据此MSDN文档,
SecurityAlgorithms
不支持验证HS512算法
- 安装jwt解码/验证库:
JWT
及其项目站点:https://github.com/jwt-dotnet/jwt
PM> Install-Package JWT -Version 7.2.1
- 使用
JWT
官方文档,并使用HS512算法修改您的示例代码,结果如下:
try
{
IJsonSerializer serializer = new JsonNetSerializer();
var provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtAlgorithm algorithm = new HMACSHA512Algorithm();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
json = decoder.Decode(token, "secretsigningkey", verify: true);
Console.WriteLine(json);
}
catch (TokenExpiredException)
{
Console.WriteLine("Token has expired");
}
catch (SignatureVerificationException)
{
Console.WriteLine("Token has invalid signature");
}
catch (Exception ex)
{
Console.WriteLine("Other exception: " + ex.Message);
}
我成功地将包System.IdentityModel.Tokens.Jwt的版本升级到6.7.1(可能没有必要(。
真正的解决方案是改变这一点:
InMemorySymmetricSecurityKey signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes("secretsigningkey"));
到这个
SecurityKey signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(domainJWTParams.IssuerSigningKey));
这适用于HS256、HS384、HS512(可能更多(,但这种实现真正好的地方在于不需要硬编码算法。