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

时间:2017-09-13 16:05:20

标签: 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构建相同的代码时,我在尝试生成令牌时遇到以下异常。

var token = tokenHandler.CreateToken(tokenDescriptor);
  

System.NotSupportedException:' NotSupported_Method'

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

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

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

2 个答案:

答案 0 :(得分:2)

而不是使用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包。

答案 1 :(得分:0)

谢谢NtFrex ..

我只是对NtFrex的答案做了些微改动,以使其对我有用。 此功能也可以与 .net 4.5.1一起使用,而且我认为这可能会对某人有所帮助。这是最终代码,但首先创建一个证书。我用过openssl用RSA512创建一个。

创建令牌:

    private string GenerateToken1()
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var certificate = new X509Certificate2(@"C:\Users\myname\my-cert.pfx", "mypassword");
        var securityKey = new X509SecurityKey(certificate);

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

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

验证令牌:

    private bool ValidateToken1(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var certificate = new X509Certificate2(@"C:\Users\myname\my-cert.pfx", "mypassword");
        var securityKey = new X509SecurityKey(certificate);

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

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

        return true;
    }