In C# How to verify JWT using ECDSA public key which was signed with ECDSA private key

时间:2018-06-04 17:30:31

标签: c# validation jwt ecdsa

I want to verify jwt which was signed through ECDSA SHA256 algorithm. Dot net library I am using is System.IdentityModel.Tokens.Jwt . I have access to public key.

2 个答案:

答案 0 :(得分:1)

如果您有权访问公共密钥,那么一种实现方法是利用JwtSecurityTokenHandler类,该类也用于生成Jwt。它在同一命名空间(System.IdentityModel.Tokens)下。

示例代码:

bool ValidateEcdsa384JwtToken(string tokenString, ECDsa pubKey) 
{
    try
    {
        var securityToken = new JwtSecurityToken(tokenString);
        var securityTokenHandler = new JwtSecurityTokenHandler();
        var validationParameters = new TokenValidationParameters() {
            ValidIssuer = securityToken.Issuer,
            ValidAudience = securityToken.Audiences.First(),
            IssuerSigningKey = new ECDsaSecurityKey(pubKey)
        };

        SecurityToken stoken;
        var claims = securityTokenHandler.ValidateToken(tokenString, validationParameters, out stoken);
        return true;
    }
    catch (System.Exception e)
    {
        return false;
    }
}

答案 1 :(得分:1)

// using System.Security.Cryptography;
// using System.Text.RegularExpressions;
// using Microsoft.IdentityModel.Tokens;

// `openssl ecparam -name prime256v1 -genkey -noout -out es256-private.pem`
// `openssl ec -in es256-private.pem -pubout -out es256-public.pem`
const string es256PublicKey = @"-----BEGIN PUBLIC KEY-----
  MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWWNSXIcIZ7iKiSnNVOzzkZEEpDvf
  sPux0GlqPl1aamHIiZgj364xcIrmaazMb1dsZaNBGLyvyJk0xRKk7BSSrg==
  -----END PUBLIC KEY-----";

// Remove all whitespace and also remove '-----XXX YYY-----'
// '\s+' Matches one or more whitespace characters
// '|' Is a logical OR operator
// '(?:        )' Is a non-capturing group
// '-+[^-]+-+' Matches one or more hyphens, followed by one or more non-hyphens, followed by one or more hyphens
var pemData = Regex.Replace(es256PublicKey, @"\s+|(?:-+[^-]+-+)", string.Empty);

var keyBytes = Convert.FromBase64String(keyData);

// Example of DER encoded P-256 curve at https://tools.ietf.org/html/rfc5759
var pointBytes = keyBytes.TakeLast(64);
var pubKeyX = pointBytes.Take(32).ToArray();
var pubKeyY = pointBytes.TakeLast(32).ToArray();

var ecdsa = ECDsa.Create(new ECParameters
  {
    Curve = ECCurve.NamedCurves.nistP256,
    Q = new ECPoint
    {
      X = pubKeyX,
      Y = pubKeyY
    }
  });

var tokenValidationParameters = new TokenValidationParameters
  {
    IssuerSigningKey = new ECDsaSecurityKey(ECDsaPublic.Value),
    ValidAlgorithms = new[]
    {
      @"ES256"
    }
  };

// https://stackoverflow.com/a/39974628/414655
var handler = new JwtSecurityTokenHandler();
var claimsPrincipal = handler.ValidateToken(jwt, tokenValidationParameters, out SecurityToken securityToken);