Friday, 11 February 2011

Finding the private key for your certificate with FindPrivateKey tool

Hi,

I had a need to find the private key file for the certificate that was stored inside the Local Computer Certificates store. I needed to set the correct permissions for the private key so that system service could access it.

When the specific Windows service started it logged the following event in my Windows Application log:

System.ArgumentException was unhandled

Message="The certificate 'CN=localhost' must have a private key that is capable of key exchange. The process must have access rights for the private key."
Source="System.ServiceModel"



The private key file actually exists but the user account under which the service runs does not have the permission for it.

Private keys for the certificates on Windows 7 and Windows Server 2008 operating systems are stored here:

C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

One example of the private key filename is:

1b2c85ebc7a8c0d84076e7da2c608e29_d6b7bae8-7a97-4c58-b63b-5f0381938d6d

And there could be tens of private key files in that directory so you do not know which private key corresponds to your certificate.

The FindPrivateKey tool solves this as it helps you to pinpoint the exact file that you are looking for.

Run the command like this:

FindPrivateKey.exe My LocalMachine -n  "CN=yourservername.domain.local"

And you will get output like this:

Private key directory:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
Private key file name:
02d5c2fdc0f71d522f6011ca8b3b1493_d6b7bae8-7a97-4c58-b63b-5f0381938d6d

So now you know on which file you need to set permissions to.

If your FindPrivateKey output return this:

FindPrivateKey failed for the following reason:
Unable to obtain private key file name

Then the user account which you use to run the FindPrivateKey tool does not have permissions to read that specific private key file you are looking for. Try running the tool with "Run as Administrator" if you are using UAC or try to run your command prompt session with LocalSystem account.

You can do this by using psexec tool from Sysinternals:

psexec -s -i cmd

The new command prompt opens that runs under LocalSystem account and you can run FindPrivateKey tool from that window.

If you still get the "Unable to obtain private key file name" then you are just out of luck :)
You will need to try and pinpoint to the correct private key file manually because neither you or the system has access to it.

Dinko

2 comments: