.net中的JWT生成和验证抛出“不支持密钥”

问题描述:

我使用以下代码生成并验证JWT。.net中的JWT生成和验证抛出“不支持密钥”

static string GenerateToken() 
{ 
    var tokenHandler = new JwtSecurityTokenHandler(); 
    var certificate = new X509Certificate2(@"Test.pfx", "123"); 
    var rsa = certificate.GetRSAPrivateKey(); 

    var tokenDescriptor = new SecurityTokenDescriptor 
    { 
     Subject = new ClaimsIdentity(), 
     Issuer = "Self", 
     IssuedAt = DateTime.Now, 
     Audience = "Others", 
     Expires = DateTime.MaxValue, 
     SigningCredentials = new SigningCredentials(
      new RsaSecurityKey(rsa), 
      SecurityAlgorithms.RsaSha256Signature) 
    }; 

    var token = tokenHandler.CreateToken(tokenDescriptor); 
    return tokenHandler.WriteToken(token); 
} 

static bool ValidateToken(string token) 
{ 
    var tokenHandler = new JwtSecurityTokenHandler(); 
    var certificate = new X509Certificate2(@"Test.cer"); 
    var rsa = certificate.GetRSAPublicKey(); 

    var validationParameters = new TokenValidationParameters 
    { 
     ValidAudience = "Others", 
     ValidIssuer = "Self", 
     IssuerSigningKey = new RsaSecurityKey(rsa) 
    }; 

    var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken securityToken); 
    if (principal == null) 
     return false; 
    if (securityToken == null) 
     return false; 

    return true; 
} 

我在一个库中有这样的代码,它的目标是.net标准2.0和net46。

当我使用该库在.NET核心应用2.0项目的一切工作正常。我使用以下nuget包。

  • System.IdentityModel.Tokens.Jwt => 5.1.4
  • System.Security.Cryptography.Csp => 4.3.0

但是,当我建立相同的代码与.net46我尝试生成令牌时会得到以下异常。

var token = tokenHandler.CreateToken(tokenDescriptor); 

System.NotSupportedException: 'NotSupported_Method'

在以下例外是抛出当我尝试验证令牌。

var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken securityToken); 

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException:“IDX10503:签名验证失败。 Keys尝试过:'Microsoft.IdentityModel.Tokens.RsaSecurityKey,KeyId: '。

而不是使用RsaSecurityKey我现在直接使用X509SecurityKey。这适用于netstandard2.0和net46。

static string GenerateToken() 
{ 
    var tokenHandler = new JwtSecurityTokenHandler(); 
    var certificate = new X509Certificate2(@"Test.pfx", "123"); 
    var securityKey = new X509SecurityKey(certificate); 

    var tokenDescriptor = new SecurityTokenDescriptor 
    { 
     Subject = new ClaimsIdentity(), 
     Issuer = "Self", 
     IssuedAt = DateTime.Now, 
     Audience = "Others", 
     Expires = DateTime.MaxValue, 
     SigningCredentials = new SigningCredentials(
      securityKey, 
      SecurityAlgorithms.RsaSha256Signature) 
    }; 

    var token = tokenHandler.CreateToken(tokenDescriptor); 
    return tokenHandler.WriteToken(token); 
} 

static bool ValidateToken(string token) 
{ 
    var tokenHandler = new JwtSecurityTokenHandler(); 
    var certificate = new X509Certificate2(@"Test.cer"); 
    var securityKey = new X509SecurityKey(certificate); 

    var validationParameters = new TokenValidationParameters 
    { 
     ValidAudience = "Others", 
     ValidIssuer = "Self", 
     IssuerSigningKey = securityKey 
    }; 

    var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken securityToken); 
    if (principal == null) 
     return false; 
    if (securityToken == null) 
     return false; 

    return true; 
} 

而且我只需要System.IdentityModel.Tokens.Jwt NuGet包,可以去除System.Security.Cryptography.Csp包。