Preface
What is PKI?
Wikipedia says: A Public Key Infrastructure (PKI) is a set of roles, policies and procedures needed to create, manage, distribute, use, store and revoke digital certificates and manage public-key encryption.
Is PKI all about public key cryptography?
Not exactly, the emphasis is more on policies and procedures rather than the technology and math.
Ok, What does this PKI thing look like?
This system consists of different parties, namely the Certificate Authority (CA), the Registration Authority (RA) and the Validation Authority (VA). These roles aren’t mutually exclusive, one party can be the CA and the VA at the same time.
Consider we want to authenticate our users using hardware tokens and certificates.
The user goes to the RA, fills some forms about personal/organization info, the RA asks the CA to create a certificate for the user and then puts the private/public keypair along with intermediate and root certificates used by the CA to sign user’s certificate into a hardware token (which acts like an HSM preventing the private key to be extracted) and delivers it to the user. (Soft Tokens can also be used)
When an application such as a website wants to authenticate the user, this hardware token is used, this token is protected with a pin number. The user having the private key sends his certificates along with his signature and then the validity of the certificate is verified by the application using a service provided by the VA.
How does the application verify identity of the client using certificateshg?
- High Level POV
From a high level point of view these phases take place:
- The client proves possession of the private key of his certificate to the server by signing what server sends to him. The server can then verify this signature using client’s public key.
- The server validates received client’s certificate, this is done by contacting the CA (or VA), the server either uses Online Certificate Status Protocol (OCSP) or the Certificate Revocation List (CRL) to see if the certificate is valid. It also verifies the parent certificates used to sign user’s certificate.
- Implementation
Now under the hood, from development point of view we have 2 basic options to implement this feature. Our example here is based on Nexus Personal (Hardware) Tokens but most of the points can be extended to other types of tokens.
Javascript API
We can use the Javascript API provided by the company which makes the token.
The code above has to be added to the page in order to enable browser-token communication.
In this case the API for Nexus Personal Tokens is named websigner (Websigner Documentation).
Here’s a sample code showing how we use the API to interact with the token:
There’s an API which uses ActiveX and there’s another one based on Mozilla NPAPI. I’m going to skip the details here, if you’re going to implement this part and need help, contact me. The scenario is that the web server generates a random number and sends it to the client, the client uses websigner2 api and asks the token to sign the number. The middleware installed on the computer asks the user to enter the pin and then the token signs the number, the signed value is then sent back to the server and the possession of private key is proved to the server. One gotcha here is that the server has to make sure the same number isn’t sent to the clients twice. So we either save it somewhere in the database or have the pool be large enough so that the chance that two generated numbers collide is negligible.
If you choose to implement the client authentication in layer 7 (the javascript API) you will have to change your application to authenticate the clients using this new method. If you’re planning to add this feature to an existing website or to a CMS you may have a hard time. (There’s another route though)
Implementing client certificate authentication using TLS might be an easier route to take because your application will undergo low or no change at all. Let’s look at this feature under IIS.
Client Certificate Mapping Authentication under Windows 2012
- Go under Add Roles and Features section.
- On Server Roles page under IIS>Web Server>Security: select Client Certificate Mapping Authentication and install this feature.
3. For ease of use and configuration, install UI Module for Client Certificate Mapping. “Client Certificates” icon will show up as indicated in the image.
Enabling Client Certificates
- Under SSL Settings Select Require SSL
- Under Client Certificates you can map windows users to client certificates, export your certificate files and move them to the server, then for each username/password combination select the corresponding certificates:
Now the user is prompted to enter the pin of his token when he enters our site, and upon successful authentication he’ll be granted access to view the pages.
Some common errors you may face are 403 errors.
403.7 – Client certificate required.
This error is shown when the client hasn’t connected his token or didn’t supply his certificate.
403.13 – Client certificate revoked.
This error can be tricky at times…
- 403.13 can mean what the title says that is the certificate was revoked and the server came up to this conclusion via OCSP or CRL.
- It can also mean that the server failed to contact the LDAP or OCSP service to get the certificate status, you can find OCSP address or CRL Distribution Point (CRLDP) under the certificate fields that’s been put into the token and test for connectivity on port 389 tcp/udp for LDAP and http connection to OCSP server.
Disabling CRL Check on IIS
Now chances are you are setting up a development environment and don’t have valid certificates or the connection to OCSP/CRLDP isn’t available at the moment and you want to go ahead and test your application, you can disable CRL check and make the web server only verify the certificate fields and the signature.
In order to do this enter “netsh http show sslcert” and find the application Id of “{4dc3e181-e14b-4a21-b022-59fc669b0914}” which corresponds to IIS. CRL check is enabled by default when you configure a web application on IIS. Now in order to disable this feature you will have to remove your current https binding and add another one.
Write down certhash and appid of your current binding, you will use these items later.
To remove current binding:
“netsh http delete sslcert ipport=0.0.0.0:443”
(change ipport configuration to point to your current binding)
To add new binding with CRL check disabled:
“netsh http add sslcert ipport=0.0.0.0:443 certhash=40db5bb1bf5659a155258d1d007c530fcb8996c2
appid={4dc3e181-e14b-4a21-b022-59fc669b0914}
certstorename=My verifyclientcertrevocation=disable”
(modify certhash and appid to point to the value you wrote down previously)
Now the CRL won’t be checked and you won’t see 403.13 error anymore.
In the upcoming blog posts I’ll discuss about how Client Certificate Authentication functions under SSL/TLS protocol and the issues you’ll face when you want to intercept the traffic in network security devices such as WAFs (Web Application Firewall).
1 Response
[…] a previous blog post I discussed about Client Certificate Authentication and possible implementation methods. In this […]