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.
Asked
Active
Viewed 2,504 times
2
-
Take a look at https://github.com/dvsekhvalnov/jose-jwt/issues/83 – Stinky Towel Jun 04 '18 at 17:59
-
I need to use System.IdentityModel.Tokens.Jwt for jwt verification. – RKN Jun 05 '18 at 15:48
2 Answers
2
If you have the access to the public key, one way of doing it is to utilise JwtSecurityTokenHandler
class which is also used to generate the Jwt. It is under the same namespace (System.IdentityModel.Tokens
).
Sample code:
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;
}
}

Stephen Rauch
- 47,830
- 31
- 106
- 135

Richard Lu
- 71
- 5
-
I have access to public key in string format, which class I will need to use create ECDsa class instance using string public key. As you mentioned in above code example, ECDsaSecurityKey constructor require to pass ECDsa class instance . – RKN Aug 18 '18 at 06:30
-
If your certificate is created with ECC algorithm, you should be able to call GetECDsaPublicKey, a method defined in X509Certificate2 class which returns an ECDsa object. Since the public key is in string format, you can use Import() method of X509Certificate2 class to construct the certificate. – Richard Lu Aug 23 '18 at 03:54
-
I found a code getting key for ES256 which is like this: byte[] publicKeyBytes = Convert.FromBase64String(pubKey); var keyType = new byte[] { 0x45, 0x43, 0x53, 0x31 }; var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 }; var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 64)).ToArray(); and then using import: CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob); ECDsaCng eCDsaCng = new ECDsaCng(cngKey); – Arvind Krmar Jun 24 '20 at 11:11
2
// 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);

Ryan Williams
- 1,465
- 15
- 19