Here's a fun question that came through the Arizona .NET User's Group list about using client certificates with ASP.NET:
Question:
How do you set up a client x509 certificate to be used by code run by an ASP.NET process? This article didn't help: http://support.microsoft.com/default.aspx?scid=kb;EN-US;901183 The WinHttpCertCfg.exe util would not install certs into the store. I had to use the mmc certificates plugin.
The workaround I did in development was to log in as the web user and install the cert into their personal cert store. Then when the code attempted to use the cert to establish a secure connection with our 3rd party service it worked.
In production, the web user is the IUSR_ account which can't log in since password is controlled by the OS. So this won't work for production.
v1.0 and v1.1 of the framework have a bug that is fixed by SP's. It always looks in the personal store for a client certificate's private key even if you grant permission to view it from the root store. For us this still seems to be the problem even with the SP applied, but v2.0 is supposed to have this fixed.
If anyone can help me, I would really appreciate it. I'm in a pinch now trying to get this resolved.
Answer:
The issue is not simply if the certificate is installed in the root or the Personal logical store name. There's more to the story, specifically which account it's installed for. In fact it needs to be in the Personal logical store name of the local computer account. (Kinda counter-intuitive, isn't it?) Shown here is an MMC console with two instances of the Certificates Snap-In added, one focused on the local computer and the other on the currently logged in user:

For those who haven't used the MMC tool with certificates before, follow along with me for a moment:
- Open MMC, then add the Certificates Snap-In. (Done by pressing CTRL-M, ALT-D, then finding the snap-in you want in the lengthy list.)
- When you choose to add this Snap-In, it needs to know which of the three account options to focus on: the computer, user, or a service account. Choose computer, and on the next screen the account for the local computer.
- Now open the Personal store for this computer account. This is where your client certificate(s) need to be imported. Each certificate must have the private key, so you have to use a .PFX file when you export / import to bring the certificate in. It's the only file type that can contain the private key.
From your question it sounds like you had gotten this far earlier, but focused on a user account instead of the computer account.
Once all the certificates you want are in the Personal store of the local computer, follow step #2 in the KB article to use WinHttpCertCfg to grant access to the certificate for ASP.NET. You must be logged on as an administrator for this to work. The -c switch selects the certificate store, which can begin with either "LOCAL_MACHINE" or "CURRENT_USER". The name "MY" refers to the same store that the MMC Snap-In calls "Personal". The -s switch chooses a SubjectStr (conveniently case insensitive), which is simply whatever name the certificate was issued to, so the same name that's listed in the first column of the Certificates Snap-In. The -a switch refers to the account being granted permission, and for ASP.NET should not be IUSR_ because when it switches over to the .NET code it's running as "Network Service" in Win2K3 or "ASPNET" in Win2K / XP. So use that for -a.
If all goes well with the WinHttpCertCfg.exe command the result should be something like this:
C:\CertCfg>WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "lorin.thwaits" -a "ASPNET"
Microsoft (R) WinHTTP Certificate Configuration Tool
Copyright (C) Microsoft Corporation 2001.
Matching certificate:
CN=Lorin.Thwaits
Granting private key access for account:
COMPUTERNAME\ASPNET
C:\CertCfg>
One final point, and you already mentioned it, is that if you're using v1.1 of the framework you need SP1. And at this point your certificate should work in production. No need to ever know the password for the ASPNET or IUSR_ account to make all this happen.