I have an AspNetCore application which generates a JWT token for me based on a PFX certificate.
public string GenerateToken()
{
using (var certificate = new X509Certificate2("certificate.pfx"))
{
var credentials = new X509SigningCredentials(certificate);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, "Name"),
new Claim(ClaimTypes.Role, "Tester"),
}),
IssuedAt = DateTime.UtcNow,
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = credentials
};
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateToken(tokenDescriptor);
return handler.WriteToken(token);
}
}
And with the same PFX you can verify if the signature is valid.
public ClaimsPrincipal ValidateToken(string token)
{
using (var certificate = new X509Certificate2("certificate.pfx"))
{
var key = new X509SecurityKey(certificate);
var validationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = key
};
var handler = new JwtSecurityTokenHandler();
try
{
var claims = handler.ValidateToken(token, validationParameters, out var validatedToken);
if (claims != null && validatedToken != null)
{
return claims;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
return null;
}
But this requires for other applications which only need to validate the JWT token to also have access to this PFX certificate.
If I take a generated token with this PFX
eyJhbGciOiJSUzI1NiIsImtpZCI6IjZEQzE4QTU4MEI4QjIxNzE4MjY5MTdDNkRGRDdGNjM5NEFBMTAwNDgiLCJ4NXQiOiJiY0dLV0F1TElYR0NhUmZHMzlmMk9VcWhBRWciLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6Ik5hbWUiLCJyb2xlIjoiVGVzdGVyIiwibmJmIjoxNTY5NDI4MDIwLCJleHAiOjE1Njk1MTQ0MTksImlhdCI6MTU2OTQyODAxOX0.kmszDk3cYEfK7dOzynotOuzTkc0GFIMbRau5ELOUROz5De-6M4YA_tWpjH1Ss6wPM078RKZeMIpolMOGvCLaza1XUp2w7fiJ_zWNJ1r4XiYzfdGiHnrUM7IwjYfwVbV7Ez2sk0FMmka-yO0UeHOKICEoxUAEBA_KzJiWHQfJJssOxcNdu4rwX1CeJ0xnJCKi77GDZ54GhdrQ_NuHzWOQZrsLa7_QfJtNTufOAzAg_kSI7XRCt6LOIkNTiENY_iJSnurlbg0O3VqkmlBvBEOS-ihd0h2Gt_AGEJ22OB4oh7Xip-xf7gm4dPR2u3ISEVmEq5H6J444CDuuKKulB7OLeKEnh9-2fGw8o-q-RIZeOo4r6UqxEW3n6TrEu7hIoAP72x5xc8ptpAPG9GtCsUjMgZcQV4QCLA9zxNxApC6J9cmgZgfI7kTGeardjsy32I23BjUl0AH0c4lh5I3SVeZB7W0mvqLj_UG_O8o57c-0dhU5kcYXJjI5gtQc1gba0ZCokA5NomnHmtpWuNvtRp4O2PwbyjM2O2RxxN07fAkPC1o4Ukm-b_n_OudyznLfmFZwv9wxqn5n-_vIy4WPuM1tm-LIzuXb0dRHDJrI8OPtj43VKNMEkQO604Fb13tVvj3iMB_n3ZWSMuLtMBLNeIED-3eynZfnr0vdMYktHNsvf6o
and place it in https://jwt.io/ I only need the public key to validate the signature.
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxd05ZB9CBfleKjaKzBTv
HylxmrEbm/yPLQKgB3oFwK4qCtcvr9dwsdK7iqFKqrmWIU/6CQrMdrx/k1s0NDWn
jdQCsnTpJ/i/rbGyasL80ilsXjOnA6G07OpvVO88Jn6J9Jz8oDsKSRpk1YV8Z6UM
pGnvlwhkhvTa43sICAPlbdc+FVzT5/3UGHiZ7D0M7I4cMLchrjQM+XP3M7AJl2vC
x/oo7twIzl/J4R5AvKlVz57NSggvyLkAIUIGEM8NpINt1f4aWEthWSLcMf8KUBJX
33MGDWb0HXaA/m1ovxWzmh001qa/miw8xl/ViurEeX9lZZjtNvW3PbV4TB4CxPUj
u61occD/Mek664PBMq+qztM22jg3tyAiIhyntDeLZtRpI3e1TwYMgF21PAc3Vskd
iuqhwFM9V/lVaRJJFJIqd94dOT20FZ78ECFCSnSEjNLaAd2Cm6WzoCf2qYPdb9ZD
2aRUm9+x0bbKxr7dFAM8mC753zuWpAPd0HGo6peAdVBQ4ZYQJ+9Px6lKcSsz4dMq
2OkoBNBCLgDaBZjfbNSxWt57OIDZpteFGgPETYf4JHs85/91JnztS/bAU1h0zrdh
L8s0l8IF89abOt5ZQ6PlwtljhMHBOjO41o/5pFo3hAEmTfv2aUjOH+amhbX9jeOJ
wFtHPr7inytlyltrrNwByeMCAwEAAQ==
-----END PUBLIC KEY-----
I would like that other application only require my public key so i do not have to distribute the PFX over multiple applications (which allows them to generate JWT tokens by themself).
How can I validate JWT tokens signed with a X509 certificate with only the public key in AspNetCore?
X509SecurityKey
that only contain a public key. Export the certificate without the private key, load up that there and see what happens? :) – juunasX509SecurityKey
is constructed is with aX509Certificate2
. See docs.microsoft.com/en-us/dotnet/api/…. Isn't there another way? – AndriesRawData
property on X509Certificate2 object and save byte array to a.CER file. Then in 2nd code snippet replace.PFX file with. CER file. – Crypt32