Testing SSL and Certificate Authentication using makecert
I 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.Tools used:
- 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 1.3.6.1.5.5.7.3.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 1.3.6.1.5.5.7.3.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:
Subject: <%=Page.Request.ClientCertificate.Subject%>
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.
Subject:
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, E=test@test.com, C=ZA" -ss my -sr CurrentUser -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.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 1.3.6.1.5.5.7.3.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, E=test@test.com, 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.