Tuesday, January 9, 2024

Verify JWT tokens with EdDSA encryption algorithm

In my previous posts of this series I showed how to generate EdDSA private and public keys pair and how to sign JWT tokens using private EdDSA key. In this last post of the series I will show how to verify signed JWT token with public key.

Let's remind that EdDSA key pair may look like that in JSON format:

{
	"kty": "OKP",
	"alg": "EdDSA",
	"crv": "Ed25519",
	"x": "...",
	"d": "..."
}

where "x" property is used for public key and "d" is for private key. Private key (d) was used for signing. For verification we need to use public key (x).
For token validation we will use JsonWebTokenHandler.ValidateTokenAsync() method from Microsoft.IdentityModel.JsonWebTokens. Here is the code which decodes token:

string token = ...;
var jwk = ...; // get EdDSA keys pair
var pubKey = new EdDsaSecurityKey(new Ed25519PublicKeyParameters(Base64UrlEncoder.DecodeBytes(jwk.X), 0));
pubKey.KeyId = jwk.KeyId;
var result = await new JsonWebTokenHandler().ValidateTokenAsync(token, new TokenValidationParameters()
{
  ValidIssuer = JwtHelper.GetServiceName(jwk),
  AudienceValidator = (AudienceValidator) ((audiences, securityToken, validationParameters) => true), // or whatever logic is needed for verifying aud claimm
  IssuerSigningKey = (SecurityKey) pubKey
});
if (!result.IsValid)
  throw result.Exception;
json = JWT.Payload(token);

Here we use EdDsaSecurityKey class from ScottBrady.IdentityModel.Tokens.
If public key matches private key which was used for signing then result.IsValid will be true (otherwise code will throw exception). At the end we call JWT.Payload() from jose-jwt to get JSON token representation (from which we may get needed claims and other data).

With these techniques you may generate EdDSA keys, sign tokens and verify them. Hopefully information in these posts will help you.