How to resolve “Keyset does not exist” error

A Windows Communication Foundation (WCF) service can use an X.509 certificate for message security with the WSHttp bindings even when the service is not configured for secure transport (https) – in other words, when wshttpBinding.Security.Mode = SecurityMode.Message. In this situation, the WCF application needs to obtain the private key of the certificate. A “Keyset does not exist” error will occur if the Windows account the IIS application is using does not have read permission on the file that contains the private key.

KeysetDoesNotExistAspnet

This explanation shows how to correct this error in IIS, but the steps are the same for any WCF application.

The steps to correct this are:

  • Locate the file that contains the private key of the certificate.
  • Grant read permission on the file to the account the IIS application is running under.

You must log on to the IIS server with an account that has administrator privileges to perform these operations.

Locate the private key file

Microsoft provides the Find Private Key Tool (http://msdn.microsoft.com/en-us/library/ms732026.aspx) to find the name and location of the private key file associated with a specific X.509 certificate in the certificate store. FindPrivateKey is included as a C# project in the Windows Communication Foundation Samples, and has to be compiled into FindPrivateKey.exe. I have compiled this and you can download FindPrivateKey.zip here.

Usage: FindPrivateKey <storeName> <storeLocation> [{ {-n <subjectName>} | {-t <thumbprint>} } [-f | -d | -a]]
 <subjectName> subject name of the certificate
 <thumbprint>  thumbprint of the certificate (use certmgr.exe to get it)
 -f            output file name only
 -d            output directory only
 -a            output absolute file name
 e.g. FindPrivateKey My CurrentUser -n "CN=John Doe"
 e.g. FindPrivateKey My LocalMachine -t "03 33 98 63 d0 47 e7 48 71 33 62 64 76 5c 4c 9d 42 1d 6b 52" -c

For www.foobar.com, the FindPrivateKey syntax might be:

FindPrivateKey My LocalMachine –n “CN=www.foobar.com”

The output will look something like this:

Private key directory:
 C:ProgramDataMicrosoftCryptoRSAMachineKeys
 Private key file name:
 6d3710272ae03c93e68fa995ce30b5eb_e2467aa4-c008-4d5f-a619-ff20d381812f

Grant read permission on the private key file

This operation has has 3 steps:

  1. Determine which Application Pool the Web site is using;
  2. Find the identity of the Application Pool;
  3. Grant read permission on the private key file for the Application Pool identity.

a. Determine which Application Pool the Web site is using.

In Internet Information Services (IIS) Manager, right-click the application and select Manage Applications and then Advanced Settings.

IIS Manager Advanced Settings

Make a note of the Application Pool name. In this example the Application Pool is AppPoolWithCertKeyReadPermission.

Click Cancel to close the dialog.
b. Find the identity of the Application Pool

In IIS Manager, in the Connections pane (left pane), select Application Pools, and make a note of the application pool identity. In this example the identity is ApplicationPoolIdentity. Another common identity is the Network Service account. The identity could also be another built-in account, or a specific user account.

Application Pools
c. Grant read permission on the private key file

In Windows Explorer, locate the private key file that was discovered in part 1. Right-click on the file, select Properties, and then select the Security tab. If you see a dialog like this, click Continue.

Security Dialog

Search for the application pool name using the identity of the application pool or the actual account name, if one was specified. The default account for IIS 7 is Network Service. You may need to select Locations and then select the local computer to limit the search scope.In this example the identity of the AppPoolWithCertKeyReadPermission application pool is ApplicationPoolIdentity, and the syntax would be as shown below (the “IIS AppPool” prefix is mandatory):

IIS AppPoolAppPoolWithCertKeyReadPermission

Check names dialog

Click Check Names.

If the name is found, the dialog will appear as shown below. (If not found, check your typing or verify again the Application Pool identity.)

SelectUsersOrGroupsDialogSuccess

Click OK to accept the account. By default, Permissions will be set to Read & Execute.

PermissionsDialog

Accept the Permissions by clicking OK.

Your WCF application will no longer throw the “Keyset does not exist” error.

Leave a Reply

Your email address will not be published. Required fields are marked *