Hi, our application needs to expose an encryption key in JWKS URL for the other party using it to encrypt their data before returning to us, and we have implemented it in IdentityServer, below is how the JWKS URL response look like:
{
"keys": [
{
"kty": "EC",
"use": "sig",
"kid": "esj_keyid",
"alg": "ES256",
"x": "nLrNw5uYtDmFjCTk0wOlukLil3gJyCEYYl5Seat0AXM",
"y": "OIgBQXQFSdvmnOFa59MTQyHhyy6t17yNIbbOFKJdQTw",
"crv": "P-256"
},
{
"kty": "EC",
"use": "enc",
"kid": "6HFIeNOix6zxe2En3bjhZJBX78OY0IG8u1KU41HeNoU",
"alg": "ECDH-ES+A192KW",
"x": "nLrNw5uYtDmFjCTk0wOlukLil3gJyCEYYl5Seat0AXM",
"y": "OIgBQXQFSdvmnOFa59MTQyHhyy6t17yNIbbOFKJdQTw",
"crv": "P-256"
}
]
}
I tried the code below, but it did not succeed in OpenIdDict:
PreConfigure< OpenIddictServerBuilder >(builder =>
{
// get ECDSA certificate
var ecdsaCertificate = CertificateHelper.GetCertificate(configuration["Key:ThumbPrint"]);
ECDsaSecurityKey ecdsaCertificatePublicKey = new ECDsaSecurityKey(ecdsaCertificate.GetECDsaPrivateKey());
// add signing key
builder.AddSigningKey(new ECDsaSecurityKey(ecdsaCertificate.GetECDsaPrivateKey()));
// add encryption credentials
var encryptionKey = JsonWebKeyConverter.ConvertFromECDsaSecurityKey(ecdsaCertificatePublicKey);
encryptionKey.KeyId = "encryption_key_id";
encryptionKey.Use = JsonWebKeyUseNames.Enc;
builder.AddEncryptionCredentials(new EncryptingCredentials(encryptionKey, SecurityAlgorithms.EcdsaSha256, "ECDH-ES+A192KW"));
});
Any idea how to do it?
17 Answer(s)
-
0
hi
Did you add
PreConfigure<OpenIddictServerBuilder>
code onPreConfigureServices
method?What is the result of
JWKS URL
after your code is added? -
0
Hi, yes, I did add the
PreConfigure<OpenIddictServerBuilder>
Below is the result of JWKS URL, it contains the signing key only:
{ "keys": [ { "kid": "NLRNW5UYTDMFJCTK0WOLUKLIL3GJYCEYYL5SEAT0", "use": "sig", "kty": "EC", "alg": "ES256", "crv": "P-256", "x": "nLrNw5uYtDmFjCTk0wOlukLil3gJyCEYYl5Seat0AXM", "y": "OIgBQXQFSdvmnOFa59MTQyHhyy6t17yNIbbOFKJdQTw" } ] }
-
0
hi
Can you try to set
AddDevelopmentEncryptionAndSigningCertificate
tofalse
?public override void PreConfigureServices(ServiceConfigurationContext context) { PreConfigure<AbpOpenIddictAspNetCoreOptions>(options => { options.AddDevelopmentEncryptionAndSigningCertificate = false; }); }
-
0
if still not working, Please share the full code to reproduce. Thanks
-
0
Hi, I did disable the development cert, below is my full PreConfigureServices:
public override void PreConfigureServices(ServiceConfigurationContext context) { var environment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); PreConfigure<OpenIddictBuilder>(builder => { builder.AddValidation(options => { options.AddAudiences("DigitalPlatform"); options.UseLocalServer(); options.UseAspNetCore(); }); }); // disable developer signing credential PreConfigure<AbpOpenIddictAspNetCoreOptions>(options => { options.AddDevelopmentEncryptionAndSigningCertificate = false; }); PreConfigure<OpenIddictServerBuilder>(builder => { // get ECDSA certificate var ecdsaCertificate = CertificateHelper.GetClientCertificate(configuration["Key:ThumbPrint"]); ECDsaSecurityKey ecdsaCertificatePublicKey = new ECDsaSecurityKey(ecdsaCertificate.GetECDsaPrivateKey()); // add signing key builder.AddSigningKey(new ECDsaSecurityKey(ecdsaCertificate.GetECDsaPrivateKey())); // add encryption credentials var encryptionKey = JsonWebKeyConverter.ConvertFromECDsaSecurityKey(ecdsaCertificatePublicKey); encryptionKey.KeyId = "encryption_key_id"; encryptionKey.Use = JsonWebKeyUseNames.Enc; builder.AddEncryptionCredentials(new EncryptingCredentials(encryptionKey, SecurityAlgorithms.EcdsaSha256, "ECDH-ES+A192KW")); }); PreConfigure<IdentityBuilder>(builder => { builder.AddSignInManager<CustomSignInManager>(); }); }
-
0
Hi @maliming, ok, let me share the full code to you.
-
0
Thanks you can create a new template project. liming.ma@volosoft.com
-
0
and you can try to use
AddSigningCertificate
instead ofAddEncryptionCredentials
-
0
Hi @maliming, I have provided the source code via email, I also attached the ECDSA cert that we use for testing.
I tried
AddSigningCertificate
, it does not work with ECDSA cert. -
0
OK
-
0
hi nhontran
The
.well-known/jwks
endpoint onlyAttachSigningKeys
.https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs#L1069
-
0
Hi @maliming, is there a way to override the handler?
-
0
hi
You can refer to its document
https://documentation.openiddict.com/guides/index.html#events-model
https://github.com/abpframework/abp/blob/dev/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs#L119 https://github.com/abpframework/abp/blob/dev/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/WildcardDomains/AbpValidateAuthorizedParty.cs
-
0
Hi @maliming, thanks, I managed to add the encryption key into JWKS URL but I got the below error when using Angular UI to login to retrieve the access token:
[09:54:04 DBG] An exception was thrown by OpenIddict.Server.OpenIddictServerHandlers+Protection+GenerateIdentityModelToken while handling the OpenIddict.Server.OpenIddictServerEvents+GenerateTokenContext event. System.ArgumentNullException: IDX10000: The parameter 'privateKey' cannot be a 'null' or an empty object. (Parameter 'privateKey') at Microsoft.IdentityModel.Tokens.EcdhKeyExchangeProvider..ctor(SecurityKey privateKey, SecurityKey publicKey, String alg, String enc)
Even the security key I put into
EncryptingCredentials
already had the private key, I have provided you the source code through email, able to help us check? -
0
hi
These are some algorithm/encryption things that I don't quite understand.
-
0
Hi, what I want to achieve is instead of using RSA key, I want to use ECDSA key for signing credentials and encryption credentials. I find this is supported by OpenIddict in their documentation:
Encryption and signing credentials To protect the tokens it issues, OpenIddict uses 2 types of credentials: Signing credentials are used to protect against tampering. They can be either asymmetric (e.g a RSA or ECDSA key) or symmetric. Encryption credentials are used to ensure the content of tokens cannot be read by malicious parties. They can be either asymmetric (e.g a RSA key) or symmetric.
but don't know why keep getting this error:
[09:54:04 DBG] An exception was thrown by OpenIddict.Server.OpenIddictServerHandlers+Protection+GenerateIdentityModelToken while handling the OpenIddict.Server.OpenIddictServerEvents+GenerateTokenContext event. System.ArgumentNullException: IDX10000: The parameter 'privateKey' cannot be a 'null' or an empty object. (Parameter 'privateKey') at Microsoft.IdentityModel.Tokens.EcdhKeyExchangeProvider..ctor(SecurityKey privateKey, SecurityKey publicKey, String alg, String enc)
Is there any sample code using ECDSA key instead of RSA key?
-
0
hi
It seems the identitymodel doesn't support the ECDSA .
Openiddict uses
identitymodel
inside.https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1291#issuecomment-1063205019