【问题标题】:WindowsCryptographicException: Keyset does not existWindowsCryptographicException:密钥集不存在
【发布时间】:2018-10-17 09:21:40
【问题描述】:

我想创建或获取证书、创建 pfx 文件、加载它并让 IdentityServer 使用它。但是,IdentityServer 无法使用我的 pfx。

如何成功创建 pfx 并让 IdentityServer 使用它?

我有一个使用 ASP.Net Core 在 localhost 上运行的 IdentityServer4 Web 解决方案。我正在准备在 Azure 上运行的生产解决方案,并将证书添加到 IdentityServer 管道,而不是开发人员签名证书。

通常这意味着像交换代码

services.AddIdentityServer()
        .AddDeveloperSigningCredential()

services.AddIdentityServer()
        .AddSigningCredential(cert)

其中“cert”是 X509Certificate2 的对象实例,它已加载包含证书(带有公钥和私钥)的 PFX 文件。

我使用的证书是自签名的,是按照 Ben Cull 的博客 https://benjii.me/2017/06/creating-self-signed-certificate-identity-server-azure/ 上的步骤创建的

证书和私钥被导出到 PFX 文件中,以便公钥和私钥都包含在文件中。

PFX 文件加载成功。加载代码是

cert = new X509Certificate2(Path.Combine(Environment.ContentRootPath, "MyPfxFile.pfx"), "password-used-when-exporting-pfx");

Pfx 文件位于 Web 项目中,可以找到并读入 X509Certificate 对象。

在 Visual Studio 中检查 X509Certificate2 时,属性 HasPrivateKey 返回 true,但 PrivateKey 属性解析为观察程序中的异常。

'cert.PrivateKey' threw an exception of type 'Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException'

所有其他属性在观察者中看起来都很好。

此外,当我在证书对象实例的即时窗口方法中执行 GetRSAPrivateKey 时,它会返回异常。

cert.GetRSAPrivateKey()
'cert.GetRSAPrivateKey()' threw an exception of type 'Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146893798
    HelpLink: null
    InnerException: null
    Message: "Keyset as registered is invalid"
    Source: "System.Security.Cryptography.Csp"
    StackTrace: "   at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)\r\n   at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()\r\n   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)\r\n   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSA
PrivateKey(X509Certificate2 certificate)"
    TargetSite: {System.Security.Cryptography.SafeProvHandle CreateProvHandle(System.Security.Cryptography.CspParameters, Boolean)}

我尝试使用 X509KeyStorageFlags 的不同设置加载 pfx 文件,但行为和异常是相同的。

我也尝试将 PFX 安装到 Windows 机器的证书管理器中,并且我已成功从那里加载它,但抛出了相同的异常。

最后,当向 IdentityServer 请求访问令牌时,会抛出相同的异常。我在下面粘贴了异常跟踪。

IdentityServer4.Hosting.IdentityServerMiddleware:Critical: Unhandled exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset as registered is invalid
   at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()
   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
   at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)
   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_HasPrivateKey()
   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.HasPrivateKey(SecurityKey key)
   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.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 209
   at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 67
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenService.cs:line 210
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 313
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAuthorizationCodeRequestAsync>d__10.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 133
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 88
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 98
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 70
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\IdentityServerMiddleware.cs:line 54
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.Message","time":"2018-10-17T09:19:34.1583055Z","tags":{"ai.application.ver":"1.0.0.0","ai.cloud.roleInstance":"HEBE","ai.operation.id":"d7c51fcd-421c862dd08fe813","ai.operation.parentId":"|d7c51fcd-421c862dd08fe813.","ai.operation.name":"POST /connect/token","ai.location.ip":"127.0.0.1","ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.internal.nodeName":"HEBE"},"data":{"baseType":"MessageData","baseData":{"ver":2,"message":"Unhandled exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset as registered is invalid\r\n   at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)\r\n   at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()\r\n   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)\r\n   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)\r\n   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()\r\n   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_HasPrivateKey()\r\n   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.HasPrivateKey(SecurityKey key)\r\n   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)\r\n   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)\r\n   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)\r\n   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)\r\n   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)\r\n   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenCreationService.cs:line 209\r\n   at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenCreationService.cs:line 67\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenService.cs:line 210\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 313\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAuthorizationCodeRequestAsync>d__10.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 133\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 88\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Endpoints\\TokenEndpoint.cs:line 98\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Endpoints\\TokenEndpoint.cs:line 70\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Hosting\\IdentityServerMiddleware.cs:line 54","severityLevel":"Critical","properties":{"DeveloperMode":"true","AspNetCoreEnvironment":"Development","{OriginalFormat}":"Unhandled exception: {exception}","exception":"Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset as registered is invalid\r\n   at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)\r\n   at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)\r\n   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()\r\n   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)\r\n   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)\r\n   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()\r\n   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_HasPrivateKey()\r\n   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.HasPrivateKey(SecurityKey key)\r\n   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)\r\n   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)\r\n   at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)\r\n   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)\r\n   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)\r\n   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenCreationService.cs:line 209\r\n   at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenCreationService.cs:line 67\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Services\\DefaultTokenService.cs:line 210\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 313\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAuthorizationCodeRequestAsync>d__10.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 133\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\ResponseHandling\\TokenResponseGenerator.cs:line 88\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Endpoints\\TokenEndpoint.cs:line 98\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Endpoints\\TokenEndpoint.cs:line 70\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\\local\\identity\\server4\\IdentityServer4\\src\\IdentityServer4\\Hosting\\IdentityServerMiddleware.cs:line 54","CategoryName":"IdentityServer4.Hosting.IdentityServerMiddleware"}}}}
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware:Error: An unhandled exception has occurred: Keyset as registered is invalid

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset as registered is invalid
   at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()
   at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
   at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)
   at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
   at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
   at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
   at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
   at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_HasPrivateKey()
   at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.HasPrivateKey(SecurityKey key)
   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.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
   at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt) in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 209
   at IdentityServer4.Services.DefaultTokenCreationService.<CreateTokenAsync>d__4.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenCreationService.cs:line 67
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Services.DefaultTokenService.<CreateSecurityTokenAsync>d__9.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Services\DefaultTokenService.cs:line 210
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<CreateAccessTokenAsync>d__14.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 313
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAuthorizationCodeRequestAsync>d__10.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 133
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.ResponseHandling.TokenResponseGenerator.<ProcessAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\ResponseHandling\TokenResponseGenerator.cs:line 88
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessTokenRequestAsync>d__7.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 98
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Endpoints.TokenEndpoint.<ProcessAsync>d__6.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Endpoints\TokenEndpoint.cs:line 70
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\IdentityServerMiddleware.cs:line 54
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at IdentityServer4.Hosting.IdentityServerMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\IdentityServerMiddleware.cs:line 72
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IdentityServer4.Hosting.BaseUrlMiddleware.<Invoke>d__3.MoveNext() in C:\local\identity\server4\IdentityServer4\src\IdentityServer4\Hosting\BaseUrlMiddleware.cs:line 43
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()

【问题讨论】:

  • 如果您已将其安装到证书存储中,您可以运行certutil -silent -store my 并共享证书的数据(我想知道的具体是“Provider”的值)。 (certutil -user -silent -store my 如果它在 CurrentUser\My 而不是 LocalMachine\My 中)
  • @bartonjs 这里是输出:------------ 序列号:b3eeb248fd720d0e 发行者:CN=abaris.no NotBefore:16.10.2018 16:25 NotAfter:13.10 .2028 16:25 主题:CN=abaris.no 签名匹配公钥根证书:主题匹配颁发者证书哈希(sha1):bb 1a b6 b9 f8 1b 27 07 93 92 64 bc c5 90 c3 43 d2 62 72 9c 密钥容器= {700D6BDE-4203-418B-A353-0BFEABAC26A7} Provider = Microsoft Enhanced Cryptographic Provider v1.0 Missing stored keyset 加密测试通过 -------------- 它还显示“缺少存储的密钥集”。 ....
  • 好的,增强型提供程序肯定应该在 CNG 中加载,但本地方同意私钥文件丢失似乎是指示性的。当您将其添加到商店时,您可能没有设置 PersistKeySey 并且密钥已被删除。为了从字节加载它,必须进行某种密钥克隆,这会导致在加载之前删除密钥。如果您在使用 PersistKeySet 加载后重新导入商店,问题可能会消失。
  • @bartonjs 我为 X509KeyStorageFlags 使用了不同的设置,包括 PersistKeySet。当 Pfx 安装到 X509Store(StoreName.My, StoreLocation.CurrentUser) 时,我已验证私钥已写入磁盘,并且进程标识对文件夹和私钥文件具有读写访问权限。在 MMC 中安装 pfx 时,证书 UI 会显示“您有一个与此证书对应的私钥”。我没有按照你的建议尝试重新导入
  • @bartonjs 我已经使用 makecert 生成了另一个证书,并且该证书现在可以使用私钥成功加载,而无需更改源代码。因此,使用 OpenSSL 生成的证书和 pfx 似乎有些东西。我很高兴现在使用 makecert,即使它已被正式弃用。

标签: asp.net-core x509certificate identityserver4


【解决方案1】:

通过添加 IIS_IUSR 组解决了该问题。 从此链接Add group IIS_IUSR

问题在于 Windows 证书存储中证书的私钥的权限没有设置 IIS_IUSRS 组以允许读取访问。

右键证书->所有任务->管理私钥->添加组“IIS_IUSRS”

【讨论】:

  • 就我而言,我的Application Pool Identity 不是IIS_IUSR,但这个答案仍然解决了我的问题;将应用程序池的身份添加到私钥的权限中修复了它。谢谢!
  • 此解决方案会有所不同,正如@codeMonkey 所指出的,它是不同的应用程序池标识。我的是一个完全不同的应用程序用户。检查您的应用了解更多详细信息 - 添加 iis_usr 可能不适合您。
  • IIS_IUSRS 组添加到证书对我有用,即使我有不同的应用程序池标识。 +1
  • 这个问题我们已经有好几个月了,现在解决了。谢谢大家。
  • @mihuilk 你是程序员中的神,谢谢!
【解决方案2】:

我也关注了那篇博文,也遇到了这个问题。 问题是当你运行它来创建 PKCS12 文件时:

openssl pkcs12 -export -out example.pfx -inkey example.key -in example.crt -certfile example.crt

尝试删除-certfile example.crt,它应该可以工作。

同样根据.NET Core X509Certificate2 usage (under Windows/IIS, Docker, Linux),您可以通过访问cert.PrivateKey 来测试证书是否从文件中正确加载。 例如

X509Certificate2 cert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "cert.pfx"), "password");
Console.WriteLine("cert private key: " + cert.PrivateKey);

【讨论】:

  • 为什么会这样?删除 -certfile example.crt 解决了这个问题。但是好像没有最后一个命令创建的pfx更小,但是用最后一个命令,它不包含私钥?
  • 我不是专家,但据我了解,-certfile file 选项允许添加证书链(除了输入证书之外,将该文件中的所有证书添加到 .p12 存储)
【解决方案3】:

在 IIS 10 上,我必须将我的应用程序池标识更改为 LocalSystem

【讨论】:

    【解决方案4】:

    哦,嘿,这是我的博文!很高兴看到它......尽管人们遇到了问题,但希望能有所帮助。说到这里,我自己也遇到了这个异常!

    我的问题是我创建了证书并尝试使用new X509Certificate2(path, password) 语法从磁盘加载它,但由于某种原因,我不得不将证书导入我的开发机器上的注册表中以阻止异常的发生。我真的不知道为什么。

    确保将证书导入CurrentUser 注册表的My/Personal 存储区。

    这个帖子有很多不同的答案,我希望其中一个对你有用,读者:)

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2012-08-19
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-08-23
      • 2019-08-21
      • 1970-01-01
      相关资源
      最近更新 更多