Open Closed

How to add encryption key in OpenIdDict JWKS URL? #4679


User avatar
0
nhontran created

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?

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

17 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Did you add PreConfigure<OpenIddictServerBuilder> code on PreConfigureServices method?

    What is the result of JWKS URL after your code is added?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    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"
        }
      ]
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try to set AddDevelopmentEncryptionAndSigningCertificate to false?

    
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
        {
            options.AddDevelopmentEncryptionAndSigningCertificate = false;
        });
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    if still not working, Please share the full code to reproduce. Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    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>();
        });
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    Hi @maliming, ok, let me share the full code to you.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Thanks you can create a new template project. liming.ma@volosoft.com

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    and you can try to use AddSigningCertificate instead of AddEncryptionCredentials

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    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.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    OK

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi nhontran

    The .well-known/jwks endpoint only AttachSigningKeys.

    https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs#L1069

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    Hi @maliming, is there a way to override the handler?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    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?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    These are some algorithm/encryption things that I don't quite understand.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    nhontran created

    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?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.