188

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?

blowdart
56.8k12 gold badges119 silver badges151 bronze badges
asked Mar 2, 2009 at 13:25

25 Answers 25

321

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.
Uwe Keim
40.9k61 gold badges193 silver badges309 bronze badges
answered Jul 4, 2010 at 21:18
Sign up to request clarification or add additional context in comments.

11 Comments

Worth noting that this isn't an option on Server 2003, unless my environment is configured wacky. I can do this on Windows 7 though.
what you mean with set private key here?? I mean you can only add the user with access right!?
Thanks, just wanted to point out that if you use iis7.5 and the application pool runs as applicationpoolidentity, you will have to give IIS AppPool\DefaultAppPool user permissions to the file. This fixed the problem for me.
I had to give permission to IIS_IUSRS to get it to work for me.
if you are getting this while running IIS express you need to give your own login permissions.
|
185

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

answered Mar 2, 2009 at 13:40

4 Comments

Running calcs helped me for a completely different issue thanks
I run my APP as administrator the the issue is gone.
+1 for the MSDN documentation and the steps listed applies even to a Web Application
Adding "NETWORK SERVICE" to the certificate security permissions resolved this for me, thanks!
41

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.

answered Dec 7, 2009 at 10:52

5 Comments

Same problem. Microsoft need to stop letting the security bozos run the asylum.
After 3 lost hours, this solves my problem - Thank you. I used the FindPrivateKey sample, and was confused why it appeared to be in my user's keystore, even when it appeared in LocalMachine through the MMC snap-in.
I'd buy you a beer for the hours wasted messing with permissions like every other answer told me to.
Thankyou thankyou thankyou! I've lost about 2.5 hours of my life thanks to this horrid issue and i'm sure i would have lost 2.5 days if i didn't see this.
I had the same issue in reverse. First installed in Local Machine, then in Current User. Removing all certs from both stores and reinstalling under Current User fixed it.
37

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 )
Sameer Alibhai
3,1984 gold badges37 silver badges36 bronze badges
answered Aug 30, 2016 at 9:09

2 Comments

If you are running under an app pool, add this user instead "IIS AppPool\DefaultAppPool"
This has helped me, too. As soon as I gave IIS_IUSRS the permissions, it started working.
23

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

answered Jan 11, 2014 at 21:51

Comments

13

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.

Richard Ev
54.4k61 gold badges196 silver badges283 bronze badges
answered Jul 9, 2013 at 14:07

Comments

10

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

Richard Ev
54.4k61 gold badges196 silver badges283 bronze badges
answered Jul 17, 2013 at 13:29

4 Comments

I tried so many things to solve this issue, but this one did the trick!
wow - was NOT expecting that to work but it did. I added IISAPPPool\www.mywebsite.com which is the windows username for my appool and it worked :-)
anybody know why this works? is something corrupted because this is pretty obscure
Don't do this! The server gets into the "bad state" where certs are being imported and showing up with the "Microsoft Software KSP" provider type when the folder ..RSA\MachineKeys has its base permissions changed. More details reddit.com/r/sysadmin/comments/339ogk/….
4

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. 
answered Aug 23, 2016 at 16:04

Comments

3

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

Nikhil
16.2k20 gold badges66 silver badges81 bronze badges
answered Oct 25, 2012 at 10:09

1 Comment

Hi this link will tell you how to resolve this issue and also locate the findprivatekey tool: blogs.msdn.microsoft.com/dsnotes/2015/08/13/…
2

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

answered Oct 1, 2019 at 8:28

1 Comment

Using "certutil -store my" was the key to solve my problem. I used the "Unique container name" to locate the file and Sysinternals Process Monitor to troubleshoot an "Access Denied" error on the certificate file. In my case I had to provide read access to the certificate file for the NT Authority\IUSR user.
2

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.

answered Sep 2, 2021 at 19:42

Comments

2

Here's the fix for in Azure.

Instead of fiddling with different KeyStorageFlags ( which describes how to store the private key on the OS) and different web.config settings.

Use EphemeralKeySet, which will load the private key in memory ( https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509keystorageflags?view=netframework-4.7.2 )

Test it out and it will work every time :)

Tip: If you need more info or other methods, read https://github.com/projectkudu/kudu/wiki/Best-X509Certificate2-Practices

answered Jun 19, 2023 at 11:37

Comments

1

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.

answered Jun 26, 2012 at 16:18

Comments

1

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

answered Jul 31, 2018 at 16:24

Comments

1

In my case, the issue was something different. Adding any permission through MMC did not change anything. I ran this in PowerShell to find out where this private key file is:

[System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey((Get-ChildItem $certStorePath | Where thumbprint -eq <YourCertThumbprint>)).key.UniqueName

Here, you should change "YourCertThumbprint" to your own certificate thumbprint. This returns the unique name of your key. I searched for this key in Windows and found out that it's stored in: "C:/ProgramData/Microsoft/Crypto/RSA/MachineKeys" Now, I right-click this file, go to permissions, and viola, I don't see any of the permissions I gave in MMC for this file, so it means MMC did not work. After I only added IIS_IUSRS permission to this file, it fixed the issue.

So, you should not always count on MMC and Microsoft Windows; you should always check that the file actually has permission.

answered Mar 21, 2023 at 22:34

Comments

0

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.

answered Aug 9, 2011 at 13:38

Comments

0

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.

answered Jan 2, 2013 at 16:44

Comments

0

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.

answered Sep 26, 2013 at 20:51

Comments

0

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

answered Apr 2, 2018 at 2:30

Comments

0

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

answered Aug 27, 2019 at 4:42

Comments

0
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.
answered Feb 25, 2020 at 7:07

Comments

0

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.

answered Nov 17, 2021 at 0:23

Comments

0

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)
answered Dec 23, 2021 at 12:31

Comments

0

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.

answered Mar 23, 2022 at 12:28

Comments

0

I'd also suggest the solution discussed here. As explained there:

The PFX has the friendlyName attribute on the key. Windows PFXImportCertStore has a race condition where opening two PFXes (including "the same PFX") that have identical friendlyName values in parallel may result in the two objects becoming inter-linked, and deleting one deletes the key out from under the other.

So, the problem was solved by removing the friendlyName attribute from the PFX file before loading it to X509Certificate2.

This code worked for me:

 public static void Foo( byte[] certificate, string pin)
 {
 using (X509Certificate2 cert = new X509Certificate2(certificate, pin,
 X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable))
 {
 if (!string.IsNullOrEmpty(cert.FriendlyName))
 {
 cert.FriendlyName = null;
 var bytesCert = cert.Export(X509ContentType.Pkcs12, pin);
 Foo(bytesCert , pin); //To reopen the certificate without the FriendlyName
 return;
 }
 cert.GetRSAPrivateKey() //It works!
 }
 }
answered Jan 10, 2024 at 22:30

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.