c# - .net 中的 JWT 生成和验证抛出 "Key is not supported"

标签 c# .net-core rsa jwt .net-standard

我正在使用以下代码生成并验证 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 构建相同的代码时,我在尝试生成 token 时遇到以下异常。

var token = tokenHandler.CreateToken(tokenDescriptor);

System.NotSupportedException: 'NotSupported_Method'

当我尝试验证 token 时抛出以下异常。

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

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: 'IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId: '.

最佳答案

我现在直接使用 X509SecurityKey 而不是使用 RsaSecurityKey。这适用于 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 包。

关于c# - .net 中的 JWT 生成和验证抛出 "Key is not supported",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46202176/

相关文章:

c# - Dotnet 核心 2 消耗高 CPU

.NET RSA 加密 : Minimum keysize?

c# - Unity Player 正在向自己射击

c# - 如何在 asmx Web 服务(wsdl)中操作端口类型?

c# - 无法将大量数据写入流

docker - dotnet core 2.2应用程序DockerFile COPY失败/over2/

c# - 谁应该负责选择合适的派生类?

c# - 网络核心 : Override WebApplicationFactory Services DbContext with InMemory Database

c# - 设置 RSA 参数

openssl - 使用命令行 openssl 执行填充 SHA256 哈希的 RSA "encryption"的方法