Granting IIS Access to a Certificate's Private Key
When you install an X.509 certificate into a cert store on your machine, only you end up having access to the private key. It turns out the private key is stored as nothing else than a file under the Documents and Settings folder. In order to give others permission to read the key (for example, an ASP.NET worker process when your WCF service is hosted), you simply have to modify the file's ACL appropriately.
I had to do this a long time ago when I first set up our secure RM interop endpoints. Back then, it was just a manual task and I ended up using WseCertificate2.exe - the WSE X.509 Certificate Tool. We recently automated the deployment and I needed a way to do this on the command line. I found out we shipped a tool in the WCF SDK called FindPrivateKey.exe just for this purpose. The tool quickly revealed the location of any private key belonging to any installed X.509 certificate. For example, I found the private key belonging to the OASIS Bob certificate with:
C:\FindPrivateKey.exe My LocalMachine -t "35 03 34 20 1b ee a6 50 2d 11 34 2f 93 ee a0 9f c0 b5 df 01"
Private key directory:
C:\Documents and Settings\onhrebic\Application Data\Microsoft\Crypto\RSA\S-1-5-21-2127521184-1604012920-1887927527-1660115
Private key file name:
7208e197d6e40f342b5e8c2629794d61_8bb36650-2933-4945-8ecb-e3c2f7042931
"35 03 34 20 1b ee a6 50 2d 11 34 2f 93 ee a0 9f c0 b5 df 01" is the key's thumbprint - for some reason I couldn't get -n "CN=Bob" to work. Combined with cacls.exe, the job was easy enough - as all the security SDK samples show:
for /f "delims='' %%i in ('FindPrivateKey.exe My LocalMachine -t "35 03 34 20 1b ee a6 50 2d 11 34 2f 93 ee a0 9f c0 b5 df 01" -a') do set PRIVATE_KEY_FILE=%%i
set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
(ver | findstr "5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R
It turns out there's another tool that's freely and more broadly available and even easier to use - WinHttpCertCfg.exe. The tool comes with the Windows Server 2003 Resource Kit Tools together with many other surprisingly useful utilities. The tool is specifically designed to work with ACLs. For example, I was able to view Bob's security list with this simple command:
C:\Program Files (x86)\Windows Resource Kits\Tools>winhttpcertcfg.exe -l -c LOCAL_MACHINE\My -s Bob
Microsoft (R) WinHTTP Certificate Configuration Tool
Copyright (C) Microsoft Corporation 2001.
Matching certificate:
CN=Bob
OU=OASIS Interop Test Cert
O=OASIS
Additional accounts and groups with access to the private key include:
DOMAIN\onhrebic
NT AUTHORITY\SYSTEM
BUILTIN\Administrators
I was than able to easily give the ASP.NET worker process permissions with:
set WP_ACCOUNT=NETWORK SERVICE
(ver | findstr "5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
C:\Program Files (x86)\Windows Resource Kits\Tools\winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s Bob -a "%WP_ACCOUNT%"