首页 > 解决方案 > Identity Server 4 WindowsCryptographicException:密钥集不存在

问题描述

在常规登录期间,我在 Identity Server 4 中得到了这两个异常以获取令牌。它在具有 2 个服务器的负载平衡设置上,所以我做了以下事情:它们都获得了相同的 PFX 来加密令牌。它在单个服务器上运行良好。他们拥有 PFX 文件的密码,并且似乎可以正确加密令牌。

有时流程运行良好,但在连接/令牌端点上授予 CORS 访问权限时总是失败。我可以看到CORS中间件在这里发挥了作用,但我不明白为什么在验证CORS访问期间签名是凭据。我在此处添加了保护,并且在启动期间,我验证了 protectionCert 和签名凭据的私钥是否存在。这两个证书都是包含在部署中的受密码保护的文件,只是为了保持简单(即不会遇到私钥访问问题)。

为什么在 CORS 操作期间突然无法访问私钥?那部分我不明白。所有这些都适用于我的测试环境,它在单台机器上运行,所以我有 99% 的把握这与这个负载平衡的设置有关。还想知道,如果我可以通过在负载均衡器中启用粘性会话来避免头疼。

在我的 DataProtection 存储中,只保存了一个密钥。不确定这是否正常。我希望应用程序能够生成更多密钥。

                    services.AddDataProtection()
                    .SetApplicationName("MyApp")
                    .PersistKeysToDbContext<DataProtectionKeyContext>()
                    .ProtectKeysWithCertificate(protectionCert);


                    var cert = new X509Certificate2("signing.pfx",
                    configuration.GetValue<string>("AppSettings:SigningCredentials:FilePassword"));
                    builder.AddSigningCredential(cert);
Unhandled exception: "Keyset does not exist" ";"Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
   at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider, CngKeyOpenOptions openOptions)
   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateTokenAsync(Token token)
   at IdentityServer4.Services.DefaultTokenService.CreateSecurityTokenAsync(Token token)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.CreateAccessTokenAsync(ValidatedTokenRequest request)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAsync(TokenRequestValidationResult request)
   at IdentityServer4.Endpoints.TokenEndpoint.ProcessTokenRequestAsync(HttpContext context)
   at IdentityServer4.Endpoints.TokenEndpoint.ProcessAsync(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
   
   
   Connection ID ""17365880169046365174"", Request ID ""800253f9-0001-f100-b63f-84710c7967bb"": An unhandled exception was thrown by the  application.";
   "Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
   at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider, CngKeyOpenOptions openOptions)
   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
   at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateTokenAsync(Token token)
   at IdentityServer4.Services.DefaultTokenService.CreateSecurityTokenAsync(Token token)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.CreateAccessTokenAsync(ValidatedTokenRequest request)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAsync(TokenRequestValidationResult request)
   at IdentityServer4.Endpoints.TokenEndpoint.ProcessTokenRequestAsync(HttpContext context)
   at IdentityServer4.Endpoints.TokenEndpoint.ProcessAsync(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
   at IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>g__InvokeCoreAwaited|15_0(HttpContext context, Task`1 policyTask)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at NewRelic.Providers.Wrapper.AspNetCore.WrapPipelineMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

标签: c#asp.netasp.net-corecryptographyidentityserver4

解决方案


我想我解决了。我读到这可能与缺乏访问权限有关。我猜我的 CD 设置中的任务无法正常工作,因为我尝试运行 APP CMD 命令将用户配置文件设置为加载为我的应用程序池的 true。假设,如果此标志为 false,应用程序将默认尝试将私钥存储为当前用户,但由于没有加载任何用户,因此这不起作用。所以我尝试使用临时密钥集(内存中)来避免访问问题,现在它可以工作了。不确定使用内存中的密钥集的后果是什么,如果密钥合适等。


推荐阅读