CryptographicException 'Keyset does not exist', but only through WCF

.NetWcfX509

.Net Problem Overview


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?

.Net Solutions


Solution 1 - .Net

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.

Solution 2 - .Net

It will probably be a permissions problem on the certificate.

When running a unit test you are going to be executing those under your own user context, which (depending on what store the client certificate is in) will have access to that certificate's private key.

However if your WCF service is hosted under IIS, or as a Windows Service it's likely it will be running under a service account (Network Service, Local Service or some other restricted account).

You will need to set the appropriate permissions on the private key to allow that service account access to it. MSDN has the details

Solution 3 - .Net

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.

Solution 4 - .Net

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 )

Solution 5 - .Net

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

Solution 6 - .Net

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.

Solution 7 - .Net

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

Solution 8 - .Net

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. 

Solution 9 - .Net

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..

Solution 10 - .Net

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

Solution 11 - .Net

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.

Solution 12 - .Net

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

Solution 13 - .Net

I was getting this same error in my PowerShell scripts. The fix for me was simply to run the script as administrator. So make sure whatever app you're running that attempts to retrieve the certificate is running as admin.

Solution 14 - .Net

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.

Solution 15 - .Net

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.

Solution 16 - .Net

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.

Solution 17 - .Net

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.

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

Solution 18 - .Net

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

Solution 19 - .Net

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.

Solution 20 - .Net

This issue is old but it surfaced to me today and all the readings I did refer to permission, but that wasn't the case with me. It turned out that the new (Windows Service) project I created had this option enabled by default. Properties-->Build-->Prefer 32-bit.

By unchecking this option and re-deploying this error went away and everything worked fine.

Hope this helps someone whose issue isn't permission-related.

Solution 21 - .Net

I was having this exception when signing a file using SNK data. The trick is to set the KeyNumber to 2 (Signature) in the CspParameters, e.g.:

$params = New-Object System.Security.Cryptography.CspParameters
$params.KeyNumber = 2

$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider($params)
$rsa.ImportCspBlob($snk)
$signature = $rsa.SignData($inputBytes, [Security.Cryptography.HashAlgorithmName]::SHA256, [Security.Cryptography.RSASignaturePadding]::Pkcs1)

Solution 22 - .Net

I experienced this exception in a race condition. I used the same PFX file about 10k times in parallel processes (maybe 50 processes in parallel) and the exception appeared in about 1 % of the cases. I assume that the processes share the same private key file and the handle counter sometimes counts wrong or something the like, and then the key file is deleted although another process still needs it.

Catching the exception and retrying to use the same X509Certificate2 object didn't help. I didn't investigate further for now, but I believe it would help to leave out the parallelization.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard EvView Question on Stackoverflow
Solution 1 - .NetSteve SheldonView Answer on Stackoverflow
Solution 2 - .NetblowdartView Answer on Stackoverflow
Solution 3 - .NetŽeljko TanovićView Answer on Stackoverflow
Solution 4 - .NetMd. Ilyas Hasan MamunView Answer on Stackoverflow
Solution 5 - .NetdesegelView Answer on Stackoverflow
Solution 6 - .NetVaibhav.InspiredView Answer on Stackoverflow
Solution 7 - .NetmuttView Answer on Stackoverflow
Solution 8 - .NetDevView Answer on Stackoverflow
Solution 9 - .Netuser1773822View Answer on Stackoverflow
Solution 10 - .NetDai BokView Answer on Stackoverflow
Solution 11 - .Netuser1483373View Answer on Stackoverflow
Solution 12 - .NetMuni ChittemView Answer on Stackoverflow
Solution 13 - .NetdeadlydogView Answer on Stackoverflow
Solution 14 - .NettygerView Answer on Stackoverflow
Solution 15 - .NetSoftwareSavantView Answer on Stackoverflow
Solution 16 - .NetJeff MinderView Answer on Stackoverflow
Solution 17 - .NetSat ThiruView Answer on Stackoverflow
Solution 18 - .NetCharithJView Answer on Stackoverflow
Solution 19 - .NetyuvrajView Answer on Stackoverflow
Solution 20 - .NetNinosView Answer on Stackoverflow
Solution 21 - .NetHugo LeoteView Answer on Stackoverflow
Solution 22 - .NetFroggyView Answer on Stackoverflow