Erlend
Erlend

Reputation: 361

WindowsCryptographicException: Keyset does not exist

I want to create or obtain a certificate, create a pfx-file, load it and have IdentityServer use it. However, IdentityServer is not able to use my pfx.

How to successfully create a pfx and have IdentityServer use it?

I have an IdentityServer4 web solution running on localhost with ASP.Net Core. I am preparing the solution for production running on Azure, and is adding a certificate to the IdentityServer pipeline instead of the developer signing certificate.

Typically this means to swap code like

services.AddIdentityServer()
        .AddDeveloperSigningCredential()

with

services.AddIdentityServer()
        .AddSigningCredential(cert)

where "cert" is an object instance of X509Certificate2 which has loaded a PFX-file containing the certificate (with public and private keys).

The certificate I am using is self signed and is created by following the steps on Ben Cull's Blog https://benjii.me/2017/06/creating-self-signed-certificate-identity-server-azure/

The certicate and private key is exported to a PFX-file in order for both public and private key to be contained in the file.

The loading of the PFX-file succeeds. The code for loading is

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

The Pfx-file is located within the web project and is found and read into the X509Certificate object.

When inspecting the X509Certificate2 in Visual Studio the property HasPrivateKey return true, but the PrivateKey property resolves to an exception in the watcher.

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

All other properties look sound and good in the watcher.

Also, when I execute the GetRSAPrivateKey in the Immediate Window method on the certificate object instance, it returns an exception.

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)}

I have tried loading the pfx-file with different settings for X509KeyStorageFlags, but the behaviour and exceptions are the same.

I have also tried to install the PFX into the Windows machine's certificate manager, and I am successfully loading it from there, but the same exceptions are thrown.

At last, when requesting an access token from IdentityServer, the same exception is thrown. I have pasted the exception trace below.

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()

Upvotes: 33

Views: 36689

Answers (7)

Hasan
Hasan

Reputation: 121

On IIS application pools select the application then advanced settings and set Identity: Localsystem and Load user profile: true enter image description here

Upvotes: 0

carbon1479
carbon1479

Reputation: 310

This issue was really bringing me grief because none of the above solutions were helping.

Here's what it was: https://improveandrepeat.com/2018/12/how-to-fix-the-keyset-does-not-exist-cryptographicexception/

I needed to go to mmc, add the Certificates snap-in, select the cert, go to All Tasks > Manage Private Keys, and add the IIS_IUSRS (or specific app pool if you prefer). I had tried doing something similar in certmgr.msc but for whatever reason the Manage Private Keys option was not available under All Tasks from that area.

Upvotes: 0

Alfredo Zamudio
Alfredo Zamudio

Reputation: 418

In my case, which by the way wasn't an API but a class library, I just had to make sure I was running visual studio in admin mode and that this user I was opening the visual studio with, was the same one who had the certificate installed in the store/mmc. Reach out if any question.

Upvotes: 1

Ben Cull
Ben Cull

Reputation: 9504

Oh hey, that's my blog post! Glad to see that it's... well hopefully helping despite problems people run into. Speaking of which I have now run into this exception myself!

My problem was that I created the certificate and tried to load it from disk using the new X509Certificate2(path, password) syntax, but for some reason I had to import the cert into the registry on my development machine to stop the exception from occuring. I'm not actually sure why.

Make sure to import the certificate to the My/Personal store of the CurrentUser registry.

There are so many different answers on this thread, I hope one of them works for you, reader :)

Upvotes: 3

Post Impatica
Post Impatica

Reputation: 16373

On IIS 10 I had to change my app pool identity to LocalSystem

Upvotes: 7

Mihuilk
Mihuilk

Reputation: 2011

The problem was resolved by adding IIS_IUSR group. From this link Add group IIS_IUSR:

The problem was that the Permissions for the Private Key of the Certificate in the Windows Certificate Store did not have the IIS_IUSRS group set to allow read access.

Right click certificate -> All Tasks -> Manage Private Keys -> Add group "IIS_IUSRS"

Upvotes: 63

Vadym Berkut
Vadym Berkut

Reputation: 193

I followed that blog post too and also had that issue. The problem was when you run this to create PKCS12 file:

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

Try to remove -certfile example.crt and it should work.

Also according to .NET Core X509Certificate2 usage (under Windows/IIS, Docker, Linux) you can test if certificate was loaded from file correctly by accessing cert.PrivateKey. E.g.

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

Upvotes: 14

Related Questions