-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ECDsa Signed JWT Support with Identity Server #1154
Comments
I think the issue may be that the SecurityKey key that gets passed to JsonWebTokenHandler needs to be a Microsoft.IdentityModel.Tokens.ECDsaSecurityKey but instead gets passed as a Microsoft.IdentityModel.Tokens.X509SecurityKey. Am I missing something in identity server configuration? |
Thanks for opening this issue. I've verified that RSA keys stored in X.509 certificates and as JWK strings work, and also EC DSA keys as a JWK string, but you may be on to something with the combination of an X.509 certificate used as the container for an EC DSA key. We'll update here with more details as we find out more. |
Thanks Joe! Do you have a sample I could see of how to store EC DSA keys as a JWK string? Our use case is a device that has EC keys baked into the trust chip, and we want to export the public key to identity server so the device can authenticate. I haven't seen a good example on how to do this. |
Sure! Within IdentityServer's main repo, we have a collection of clients that we use internally for development and testing, and that's where I verified the EC DSA as a JWK. Those clients aren't as straightforward to use as the code we package up as an official sample in our samples repo, but I think it shows what you need to do. I've just opened a PR - take a look: DuendeSoftware/IdentityServer#1528. |
Thanks Joe-- we got it working from that! That totally unblocked me. Except for embedding it in identity server secrets, we're using the following code to create the EC keys from the public keys, and roughly the same for the private keys: var x = publicKey.Skip(1).Take(32).ToArray(); var publicEcdsa = ECDsa.Create(new ECParameters It would be nice if this was just a new parsable secret, and instead of using the JWK we could just use the public key and tell it to use an EC signature... |
Glad to hear you're unblocked. I've added the issue linked above to investigate how we can make this scenario more convenience. For now, I'll go ahead and close this issue, but feel free to follow up if you have more thoughts/questions/concerns! |
Which version of Duende IdentityServer are you using?
7.0.1
Which version of .NET are you using?
8.0
Describe the bug
I cannot get ECDsa certificate signed JWTs to work with Identity Server. It works fine with RSA but I need this to work with EC keys. To get this working, I started with the sample code, which adds the following in Startup:
builder.AddJwtBearerClientAuthentication();
I did not add anything special in IdentityServer to add EDCsa support, so perhaps that's something that's needed? I did test with an RSA signed JWT and it worked, but then fails with EC keys.
To Reproduce
Configure the public key of the ECDsa certificate as a client secret in IdentityServer.
Create a JWT and sign it using a ECDsa certificate.
Send that to request an auth token from Identity Server.
Expected behavior
Expect it to work. Instead get a failure in JwtTokenHandler, as it doesn't seem to understand EC keys.
Log output/exception with stacktrace
Additional context
I replaced the secret validator and my own token handler to try to mimic the Microsoft code and debug it to try to see what's happening, and find that Microsoft's implementation fails in this method of JwtTokenHandler:
That returns false, which causes the validation to fail, which results in a more generic error message.
In the PrivateKeyJwtSecretValidator given the following code:
I can see that I have the expected matching signing key, and it is able to resolve it using the InternalId from the x5t header.
Deep in Microsoft's code I see the following:
internal static bool ValidateSignature(JsonWebToken jsonWebToken, SecurityKey key, TokenValidationParameters validationParameters)
{
var cryptoProviderFactory = validationParameters.CryptoProviderFactory ?? key.CryptoProviderFactory;
// The cryptoProviderFactory.IsSupportedAlgorithm method returns false which returns a failure:
if (!cryptoProviderFactory.IsSupportedAlgorithm(jsonWebToken.Alg, key))
In Clients.cs (using sample/starter code) I added the following secret (which works with a RSA key and RSA signed JWTs):
On the client, I'm using the following code for the header:
var tokenHeader = new Dictionary<string, string> { { "alg", "ES384" }, { "typ", "JWT" } }; tokenHeader.Add("x5t", Base64UrlEncoder.Encode(cert.GetCertHash()));
In Identityserver, this seems to resolve to the signing key, but then it doesnt seem to know that it should be using ECDsa and fails on the call to IsSupportedAlgorithm inside of Microsoft's library.
The text was updated successfully, but these errors were encountered: