[.net] CryptographicException 'Keyset does not exist', but only through WCF

I have some code that makes a call to a third party web service that is secured using X.509 certification.

If I call the code directly (using a unit test) it works without any problems.

When deployed, this code will be called via a WCF Service. I have added a second unit test that calls the WCF Service, however this fails with a CryptographicException, message "Keyset does not exist" when I call a method on the third party web service.

I presume that this is because my WCF Service will be attempting to call the third party web service using a different user to myself.

Can anyone shed any additional light on this issue?

This question is related to .net wcf x509

The answer is


To solve the “Keyset does not exist” when browsing from IIS: It may be for the private permission

To view and give the permission:

  1. Run>mmc>yes
  2. click on file
  3. Click on Add/remove snap-in…
  4. Double click on certificate
  5. Computer Account
  6. Next
  7. Finish
  8. Ok
  9. Click on Certificates(Local Computer)
  10. Click on Personal
  11. Click Certificates

To give the permission:

  1. Right Click on the name of certificate
  2. All Tasks>Manage Private Keys…
  3. Add and give the privilege( adding IIS_IUSRS and giving it the privilege works for me )

Totally frustrating, I had the same issue and tried most of the above. The exported certificate correctly had permissions to read the file in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, however as it turns out it didn't have permission on the folder. Added it and it worked


I just wanted to add a sanity check answer. I was getting the exact same error even after installing the certificates to the right stores on my machines and having all the right security privileges for the client. Turns out I mixed up my clientCertificate and my Service Certificate. If you have tried all of the above, I would double check that you have those two straight. Once I did that, my application successfully called the web service. Again, just a sanity checker.


This is most likely because the IIS user doesn't have access to the private key for your certificate. You can set this by following these steps...

  1. Start ? Run ? MMC
  2. File ? Add/Remove Snapin
  3. Add the Certificates Snap In
  4. Select Computer Account, then hit next
  5. Select Local Computer (the default), then click Finish
  6. On the left panel from Console Root, navigate to Certificates (Local Computer) ? Personal ? Certificates
  7. Your certificate will most likely be here.
  8. Right click on your certificate ? All Tasks ? Manage Private Keys
  9. Set your private key settings here.

I just reinstalled my certificate in local machine and then it is working fine


I've had identical issue last night. Permissions on private key were set correctly, everything was apparently fine except the Keyset doesn't exist error. In the end it turned out that certificate was imported to the current user store first and then moved to local machine store. However - that didn't move the private key, which was still in the

C:\Documents and settngs\Administrator...

instead of

C:\Documents and settngs\All users...

Altough permissions on the key were set correctly, ASPNET couldn't access it. When we re-imported certificate so that private key is placed in the All users branch, the problem disappeared.


Had the same problem while trying to run WCF app from Visual Studio. Solved it by running Visual Studio as administrator.


This issue is got resolved after adding network service role.

CERTIFICATE ISSUES 
Error :Keyset does not exist means System might not have access to private key
Error :Enveloped data … 
Step 1:Install certificate in local machine not in current user store
Step 2:Run certificate manager
Step 3:Find your certificate in the local machine tab and right click manage privatekey and check in allowed personnel following have been added:
a>Administrators
b>yourself
c>'Network service'
And then provide respective permissions.

## You need to add 'Network Service' and then it will start working.

This is the only solution worked for me.

    // creates the CspParameters object and sets the key container name used to store the RSA key pair
    CspParameters cp = new CspParameters();
    cp.KeyContainerName = "MyKeyContainerName"; //Eg: Friendly name

    // instantiates the rsa instance accessing the key container MyKeyContainerName
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
    // add the below line to delete the key entry in MyKeyContainerName
    // rsa.PersistKeyInCsp = false;

    //writes out the current key pair used in the rsa instance
    Console.WriteLine("Key is : \n" + rsa.ToXmlString(true));

Reference 1

Reference 2


I have faced this issue, my certificates where having private key but i was getting this error("Keyset does not exist")

Cause: Your web site is running under "Network services" account or having less privileges.

Solution: Change Application pool identity to "Local System", reset IIS and check again. If it starts working it is permission/Less privilege issue, you can impersonate then using other accounts too.


I hit this in my service fabric project after the cert used to authenticate against our key vault expired and was rotated, which changed the thumbprint. I got this error because I had missed updating the thumbprint in the applicationManifest.xml file in this block which precisely does what other answers have suggested - to given NETWORK SERVICE (which all my exes run as, standard config for azure servicefabric cluster) permissions to access the LOCALMACHINE\MY cert store location.

Note the "X509FindValue" attribute value.

_x000D_
_x000D_
<!-- this block added to allow low priv processes (such as service fabric processes) that run as NETWORK SERVICE to read certificates from the store -->_x000D_
  <Principals>_x000D_
    <Users>_x000D_
      <User Name="NetworkService" AccountType="NetworkService" />_x000D_
    </Users>_x000D_
  </Principals>_x000D_
  <Policies>_x000D_
    <SecurityAccessPolicies>_x000D_
      <SecurityAccessPolicy ResourceRef="AzureKeyvaultClientCertificate" PrincipalRef="NetworkService" GrantRights="Full" ResourceType="Certificate" />_x000D_
    </SecurityAccessPolicies>_x000D_
  </Policies>_x000D_
  <Certificates>_x000D_
    <SecretsCertificate X509FindValue="[[THIS KEY ALSO NEEDS TO BE UPDATED]]" Name="AzureKeyvaultClientCertificate" />_x000D_
  </Certificates>_x000D_
  <!-- end block -->
_x000D_
_x000D_
_x000D_


If you use ApplicationPoolIdentity for your application pool, you may have problem with specifying permission for that "virtual" user in registry editor (there is not such user in system).

So, use subinacl - command-line tool that enables set registry ACL's, or something like this.


I found some missing information that helped me get my WCF service with Message level security past the "Keyset does not exist" that I kept running into despite granting permissions to all the keys generated from the examples on the internet.

I finally imported the private key into the trusted people store on local machine and then granted the private key the correct permissions.

This filled in the blanks for me and finally allowed me to implement the WCF service with Message level security. I am building a WCF that must be HIPPA compliant.


The Answer from Steve Sheldon fixed the problem for me, however, as I am scripting certificate permissions with out a gui, I needed a scriptable solution. I struggled to find where my private key was stored . The private key was not in -C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys , eventually I found that it was actually in C:\ProgramData\Microsoft\Crypto\Keys. Below I describe how I found that out:

I tried FindPrivateKey but it could not find the private key, and using powershell the $cert.privatekey.cspkeycontainerinfo.uniquekeycontainername was null/empty.

Luckily, certutil -store my listed the certificate and gave me the details I needed to script the solution.

================ Certificate 1 ================ Serial Number: 162f1b54fe78c7c8fa9df09 Issuer: CN=*.internal.xxxxxxx.net NotBefore: 23/08/2019 14:04 NotAfter: 23/02/2020 14:24 Subject: CN=*.xxxxxxxnet Signature matches Public Key Root Certificate: Subject matches Issuer Cert Hash(sha1): xxxxa5f0e9f0ac8b7dd634xx Key Container = {407EC7EF-8701-42BF-993F-CDEF8328DD} Unique container name: 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a ##* ^-- filename for private key*## Provider = Microsoft Software Key Storage Provider Private key is NOT plain text exportable Encryption test passed CertUtil: -store command completed successfully.

I then scanned c\ProgramData\Microsoft\Crypto\ folder and found the file 8787033f8ccb5836115b87acb_ca96c65a-4b42-a145-eee62128a in C:\ProgramData\Microsoft\Crypto\Keys .

Giving my service account read access this file fixed the issues for me


I have exactly similar problem too. I have used the command

findprivatekey root localmachine -n "CN="CertName" 

the result shows that the private key is in c:\ProgramData folder instead of C:\Documents and settngs\All users..

When I delete the key from c:\ProgramData folder, again run the findPrivatekey command does not succeed. ie. it does not find the key.

But if i search the same key returned by earlier command, i can still find the key in

C:\Documents and settngs\All users..

So to my understanding, IIS or the hosted WCF is not finding the private key from C:\Documents and settngs\All users..


Received this error while using the openAM Fedlet on IIS7

Changing the user account for the default website resolved the issue. Ideally, you would want this to be a service account. Perhaps even the IUSR account. Suggest looking up methods for IIS hardening to nail it down completely.


I was getting the error : CryptographicException 'Keyset does not exist' when i run the MVC application.

Solution was : to give access to the personal certificates to the account that application pool is running under. In my case it was to add IIS_IUSRS and choosing the right location resolved this issue.

RC on the Certificate - > All tasks -> Manage Private Keys -> Add->  
For the From this location : Click on Locations and make sure to select the Server name. 
In the Enter the object names to select : IIS_IUSRS and click ok. 

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to wcf

Create a asmx web service in C# using visual studio 2013 WCF Exception: Could not find a base address that matches scheme http for the endpoint WCF Service, the type provided as the service attribute values…could not be found WCF error - There was no endpoint listening at How can I pass a username/password in the header to a SOAP WCF Service The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM' Content Type application/soap+xml; charset=utf-8 was not supported by service The content type application/xml;charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8) maxReceivedMessageSize and maxBufferSize in app.config how to generate a unique token which expires after 24 hours?

Examples related to x509

How can I generate a self-signed certificate with SubjectAltName using OpenSSL? How to read .pem file to get private and public key Extract public/private key from PKCS12 file for later use in SSH-PK-Authentication Getting RSA private key from PEM BASE64 Encoded private key file How to convert .crt to .pem Using HTTPS with REST in Java What does "subject" mean in certificate? CryptographicException 'Keyset does not exist', but only through WCF