Cannot use self issued client certificate

httpsiisSecuritysslssl-certificate

I want to be able to create a test client certificate signed by a test CA and establish a SSL connection and identify the client using this certificate using IIS7 and Firefox on Windows 7, all locally on a development machine. I am deploying my MVC application from VS2010. So far I have done the following:

  1. Created the CA using:

    makecert -n "CN=mydomain" -r -pe -sv DevCA.pvk DevCA.cer -sr LocalMachine -a sha1 -sky signature -cy authority

  2. Create a client certificate signed by DevCA:

    makecert -sv testclient.pvk -iv DevCA.pvk -pe -a sha1 -sky Exchange -eku 1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2 -n "CN=mydomain" -ic DevCA.cer testclient.cer -ss My -sr LocalMachine

  3. Create PFX files of the two certificate:

    pvk2pfx.exe -pvk testclient.pvk -spc testclient.cer -pfx testclient.pfx

    pvk2pfx.exe -pvk DevCA.pvk -spc DevCA.cer -pfx DevCA.pfx

  4. Use certmgr to import DevCA to trusted root certificates

  5. In IIS manager:

    a) Added testclient.pfx to 'Server Certificates'

    b) In my site, set SSL Settings to accept SSL

    c) Set HTTPS bingings to use testclient certificate

  6. In Firefox I then add DevCA to Authorities tab and testclient to 'Your Certificates', in IE I import CA and client certificates using certmgr.

When I navigate to my application in Firefox using HTTPS I get:

"Connection is untrusted"

In IE I get:

"HTTP Error 403.16 – Forbidden, Your client certificate is either not trusted or is invalid."

If I then add an exception I can establish an SSL connection but within my application I cannot get details of the client certificate using:

HttpClientCertificate cert = this.Request.ClientCertificate;
if (cert.IsPresent)
etc..

Not sure what I'm doing wrong here. Any ideas?

Best Answer

To use client certificate authentication you need both:

  1. server certificate (your testclient.pfx that you've added to IIS Server Certificates)
  2. client certificate (available to browser) - you missed that point.

Server certificate provides secure SSL connection. To make server trusted to browsers you've added DevCA (that was used to sign testclient certificate for your server). If you configure your IIS to ignore client certificates then you've got ordinary secure communication scenario - connection is secured, but client isn't authenticated (no prompt for user certificate in browser).

Next step - ensure setting your IIS to accept client certificates. Browser will prompt user to choose certificate if it's available but will allow user to cancel request of certificate and continue browsing - that is your case. Request.ClientCertificate is empty.

To authenticate client (user) with certificate you should issue a separate certificate (one certificate per user). You can use same DevCA to sign new client certificate (see this article).

makecert -sk MyKeyName1 -iv DevCA.pvk -n "CN=Client1AuthCert" -ic DevCA.cer -sr currentuser -ss my -sky signature -pe

User installs that certificate on his/her computer to Personal Certification Store and also installs Issuer Cert (DevCA) to trusted root certificate authorities. When user opens browser with your web app, certificate prompt will be shown:

user certificate prompt

When user chooses certificate, it will be available in Request.ClientCertificate property on a server. User certificate is used as a credential in this case (instead of user/password, etc).

If you don't want user access your web app without having client certificate at all, you can set SSL settings to require client certificate.