Accessing a private key for a certificate 

I ran into an interesting issue yesterday with trying to access the private key of a certificate. Why I needed to do that, isn’t really relevant for this post, but the trouble I ran into is something worth sharing.

 

First of all, you need a certificate with an exportable key: you can do so when you import the certificate into the certificate store. So far so good, this is easy. It got alot worse after that: while trying to open the certificate’s private key, I got an error saying: “Handle is invalid”. Thanks very much for this very descriptive error… What this basically means is that, in my case, the ASP.NET application does not have access the private key. Or better: the identity the application pool uses does not have access to the private key, which is stored on disk. This can be solved by downloading the Winhttpcertcfg tool from Microsoft. This tool allows you to add permissions on the private key of the certificate. You have to run the tool from the command-line (it is located in C:\Program Files\Windows Resource Kits\Tools) and specify the store, certificate issuer and the user you want to grant access to.

Example:

winhttpcertcfg -g -c LOCAL_MACHINE\MY -s <Certificate Issuer> -a <Account name>

Ok fine, the “Handle is invalid” error had disappeared, but now I got another error: “System cannot find the file specified”. Hmm, okay, another very clear error message. Thanks again, I started to wonder whether using the System.Security.Cryptography also means that you get cryptic error messages along with it. Problem was though, that my application pool was configured to use a custom account. When I switched this to the default Network Service account there wasn’t a single problem. It turned out that the RSACryptoServiceProvider class tries to access the user profile of the configured account in the application pool. But since this user has not logged in to the machine yet (and probably never will), it cannot access the directories.

You can find a more detailed explanation on this other blog site I ran into while investigating the problem: http://blogs.msdn.com/alejacma/archive/2007/12/03/rsacryptoserviceprovider-fails-when-used-with-asp-net.aspx

All that I needed to do now, was directing the RSACryptoServiceProvider instance to the machine certificate store by adding parameters with the constructor:

   1: var rsaParameters = new CspParameters
   2:                         {
   3:                             Flags = CspProviderFlags.UseMachineKeyStore
   4:                         };
   5: var rsa = new RSACryptoServiceProvider(rsaParameters);

After the change in code, everything worked just fine.

Posted on 18-03-2009 by Arnold Jan van der Burg
0 Comments  |  Trackback Url  |  Link to this post
Tags:

Links to this post

Comments

Name:
URL:
Email:
Comments:

CAPTCHA Image Validation