Testing SSL and Certificate Authentication using makecertI wanted to set up a development environment, all on my local PC, that would allow me to do Certificate Authentication in an ASP.NET application.
- IIS 5.1 / Windows XP
- Web browser: IE 6.0
- IIS Resources / WFetch for troubleshooting HTTP issues
First we create a "Root CA" for our two certificates:
makecert -pe -n "CN=Dev Root Auth" -ss my -sr LocalMachine -a sha1 -sky signature -r "DevRootAuth.cer"Open MMC. Add the Certificates snap-in for Local Computer.
Copy and paste the above "Dev Root Auth" certificate from the Personal path to the "Trusted Root Certification Authorities" path. Or use certmgr to copy it:
certmgr -add -all -c "DevRootAuth.cer" -s -r LocalMachine RootNow create the server certificate (to use for SSL), using the first certificate created above as the Issuer:
makecert -pe -n "CN=localhost" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 188.8.131.52.184.108.40.206.1 -in "Dev Root Auth" -is MY -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 localhost.cerNote the "Extended Key Usage" value of 220.127.116.11.18.104.22.168.1 which indicates that this cert is for Server Authentication.
Now enable SSL: open Inetnet Information Services management console. Right-click Default Web Site and go to Properties -> Directory Security -> Server Certificate -> Assign an existing certificate. Select the "localhost" cert. Finish the wizard.
You should now be able to access pages on your localhost with HTTPS.
For example, create a directory C:\inetpub\wwwroot\SecureTest with a file named Default.aspx containing the following three lines:
Cert present: <%=Page.Request.ClientCertificate.IsPresent%>Open now open the file in IE as https://localhost/SecureTest/default.aspx. The output will show:
Cert present: FalseThis verifies HTTPS is working. When you click the padlock icon in Internet Explorer you should see the "localhost" certificate is OK. We're done setting up SSL.
The next step is to create the Client Authentication certificate, which IE will pass to IIS to authenticate the user.
makecert -pe -n "CN=Test Client, O=Test company, OU=Testing, Eemail@example.com, C=ZA" -ss my -sr CurrentUser -a sha1 -sky exchange -eku 22.214.171.124.126.96.36.199.2 -in "Dev Root Auth" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 testclient.cerNote this time the Extended Key Usage value is 188.8.131.52.184.108.40.206.2 which indicates that this cert is for Client Authentication.
The Subject string (-n parameter) must conform to the X.500 distinguished names standard. See RFC2253 for a description of the possible X.500 attributes. You can also use E to specify an email address. I found that the UID attribute doesn't work with makecert, which is too bad, because it would be nice to be able to assign a custom field to the cert to easily identify the user.
You can now configure the SecureTest application in IIS to require Certificate Authentication. In IIS manager, right-click on the SecureTest directory and to Properties -> Directory Security -> Edit. Click "Require secure channel (SSL)". Click "Require client certificates". Click OK and OK again.
Now open https://localhost/SecureTest/default.aspx in IE again. This time the output should show:
Cert present: TrueThis verifies the Certificate Authentication works.
Subject: C=ZA, Efirstname.lastname@example.org, OU=Testing, O=Test company, CN=Test Client
To make this more useful, you would use the certificate ("what you have") in your Login screen in addition to (or instead of) a username/password ("what you know") for a two-factor authentication scheme. You could map the client certificate to a Windows user in IIS, or write custom authentication code (e.g. Forms Authentication) using the certificate information to uniquely identify the user... (Although some might argue that using a certificate doesn't mean it's a two-factor scheme).
Remember to use WFetch during the whole process to test everything - it's much easier troubleshooting HTTP issues (e.g. to see the HTTP request and response headers and status codes) than just testing with IE.