I wanted to get client certificate authentication working on a development environment. The environment in this case is a Windows 8.1 laptop so that implies IIS 8.5. It involves a significant number of steps so this will be a long post.

Configure IIS

First of all, you need to configure IIS to allow client certificate mapping authentication. As you can see in the screenshot below, there are two types of these. We need the IIS Client Certificate Mapping Authentication feature. The Client Certificate Mapping Authentication feature is used for client certificate authentication using Active Directory.

Windows Features

Generate certificates

Next step is to generate certificates. Client certificate authentication requires that your website has an HTTPS binding so we first need a certificate for the server. To obtain this, we use a self-signed certificate that we add to the trusted root certificates store of the local computer and we derive both the client and the server certificate from this root certificate.

Self-signed root certificate

To generate the root certificate, use the following command line:

makecert -r -pe -n "CN=WebSSLTestRoot"
         -b 12/22/2013 -e 12/23/2014
         -ss root -sr localmachine -len 2048

The makecert command has a lot of options, some of which we use here:

-r Generate a self-signed certificate.
-pe Allow the private key to be included in the certificate. We need this because we want to use the certificate to issue other certificates that are signed by this private key.
-n "name" Certificate subject name.
-b Validity start date.
-e Validity end date.
-ss Name of the certificate store that stores the certificate. Since we want to automatically trust this certificate, we store it with the trusted root certificates. You can find some more info on store locations here.
-sr Certificate store location where the certificate will be stored (either currentuser or localmachine).
-len Key length.

The result is a trusted root certificate as you can see in the screenshot below.

Self-signed root certificate

Server certificate

We derive the IIS server certificate from the root certificate we just generated with the following command:

makecert -pe -n "CN=www.sslclientauth.local" -b 12/22/2013 -e 12/23/2014
         -eku -is root -ir localmachine -in WebSSLTestRoot
         -len 2048 -ss WebHosting -sr localmachine

This is no longer a self-signed certificate since we derive it from our own root certificate so the -r option is gone. Note that we use the subject name www.sslclientauth.local. This will become the url for the web site. Besides, we now store the certificate in a LocalMachine store called WebHosting. The new options we're using are to describe the purpose of this certificate and to locate the issuing (root) certificate we generated before:

-eku Describes the purpose of this certificate, which is to authenticate a server. Check here for more information on certificate OID's.
-is The name of the certificate store where our issuing certificate resides.
-ir The certificate store location of our issuing certificate.
-in The subject name of our issuing certificate.

The result is a certificate that can be used to verify the authenticity of a server, in this case a server named www.sslclientauth.local. The certificate is trusted because it is signed by a trusted (root) certificate as you can see in the following screenshot.

Server certificate

Client certificate

The last certificate we need is the client certificate. Since we already have a root certificate, let's derive the client certificate from it as well:

makecert -pe -n "CN=SSLClientAuthClient"
         -eku -is root -ir localmachine -in WebSSLTestRoot
         -ss my -sr currentuser -len 2048

No new makecert are introduced here. The key purpose this time is client authentication and we store the certificate in the CurrentUser personal store.

Client certificate

Configure a test web application

I generated an empty ASP.NET 4.5.1 web project and added a basic 'hello world' page. Next step is to configure IIS. We add a new website and configure an https binding as shown in the following screenshot. The physical path points to the website I just created.

Add IIS website

Most important are the https binding, the host name and the certificate. Make sure that host name and certificate match. The certificate that's selected in the screenshot is the one we created earlier. It can only be selected from the LocalMachine Personal or WebHosting stores, which is why I added the certificate to the latter.

The checkbox Require Server Name Indication (SNI) requires clients (browsers) to use the SNI extension to the TLS protocol.

Last step is to update your hosts file (in %systemroot%System32driversetc) to include the following line: www.sslclientauth.local. This maps the address www.sslclientauth.local to localhost.

If all went well, you now have a website running with HTTPS. You can easily check this by visiting https://www.sslclientauth.local in a browser. Now for the client authentication part.

Configure client authentication

We already have a client certificate so all we need to do is tell the server that only clients using this particular certificate may enter and configure a client to use the certificate.

To configure the server part, first we must export the public key part of the certificate in base64 format. To do this, right-click your certificate in the MMC Certificate Snap-in and select All Tasks → Export.... Do not export the private key, select the base-64 format and a place to store the certificate. Open the certificate with a text editor, remove the BEGIN and END CERTIFICATE lines and make sure the certificate itself is on one line.

Now that we have the certificate, configure the server to actually use it for authentication. First configure your website to require client certificates:

SSL Settings

Next, open up the Configuration Editor for the website..

Configuration Editor

..and enter the following into the Section: text box: system.webServer/security/authentication/iisClientCertificateMappingAuthentication. Change enabled to True and click on the ellipsis on the right of oneToOneMappings. Click on the Add on the right of the dialog and paste your client certificate value to the right place (make sure it's really one line of text). Next, enter a valid username and password for your local environment.

One to one mapping config

Exit the dialog and apply the changes. These changes will be applied not to your Web.config file but to your applicationHost.config file (in %systemroot%System32inetsrvconfig).


We should now have a valid setup that you can test so we open up a browser and go to https://www.sslclientauth.local. The browser should ask for a certificate:

Browser requests certificate

And we finally have access to our website!

Things that can go wrong

Incorrect username or password

When you do not enter a username and password or you enter incorrect values, the error you receive is a 401.1 - Unauthorized. This may suggest that there is something wrong with your certificate but that doesn't have to be the case. If you've entered incorrect credentials, you'll see error code 0x8007052e, as in the following screenshot.

Invalid mapped credentials

Base64 client certificate incorrect

You have had to export the client certificate to base64 and then open the file in a text editor, remove the begin and end lines and remove all CRLF's. Something may have gone wrong in the process so you end up with an incorrect or invalid base64 string. You'll get a 401.1 - Unauthorized again. However, this time you see either error code 0x80093102 or 0x8009310b.

And finally...

Keep in mind that all we have done is to configure authentication, not authorization! If I present another client certificate that has a valid trust chain, I can gain access to the site as well. In one of the last screenshots you see a certificate named SSLClientAuthClient2. If I select that one, I also see my hello world page. The difference between both access attempts is that with a valid certificate I enter my website with an authenticated principal while with the invalid certificate I'm not authenticated. You'll have to specify authorization rules for your website or part of your website to actually deny users access.

Related articles

  • Cloud Native
  • Application Navigator
  • Kubernetes Platform
  • Digital Workspace
  • Cloud Infrastructure
  • ITTS (IT Transformation Services)
  • Managed Security Operations
  • Multi-Cloud Platform
  • Backup & Disaster Recovery
Visit our knowledge hub
Visit our knowledge hub

Let's talk!

Knowledge is key for our existence. This knowledge we use for disruptive innovation and changing organizations. Are you ready for change?

"*" indicates required fields

First name*
Last name*