javascriptsslcertificatecac

How Do You Program a Website to Use a Certificate for Authentication?


My company is looking at using card based certificates (like CACs) for authentication on a web site; instead of the user entering a username and password this information would be extracted from the certificate. How does one go about programming the front end to pass the certificate on to the webserver? I've been looking for specific directions but wind up with everything but that. The over all idea is to hook into something like an LDAP for authentication eventually, but the browser part is completely eluding me.


Solution

  • You don't really have to do much in the way of the client side stuff. For a website, the browser handles it for you. You just have to setup your server to require a client certificate and the browser will handle it. Under Apache, after setting up the SSL certificate, this is as simple as setting SSLVerifyClient required (manual) in the apache configuration. Your site will then require a client certificate for access. You can also set SSLVerifyClient to optional which allows someone to click "Cancel" when prompted to select a certificate and the site will still load, but is missing the environment variables (see below).

    If you are using smart cards, you might need a driver for the smart card reader to prompt the user for a pin to query the card, but it isn't something you need to handle. In my experience (with CAC cards), both Internet Explorer and Firefox use a third party software (we use ActiveIdentity) to ask for the user's pin (Firefox needs to be setup to use a "Security Device", but it is simple) and Chrome already has built in support for the smart cards without needing a separate program. It is also possible to install the certificate in the browser, but I haven't worked with that.

    As for validating the user, in Apache, once the SSL handshake stuff has been completed by the browser and server, in PHP there are several environment variables that are available (you can see them on a phpinfo() page or if you print_r($_SERVER). They are all SSL_* and include stuff like the domain or common name). This can differ based on what information was supplied from the client. We just found one that held a unique id for the card $_SERVER['SSL_CLIENT_S_DN_CN'] and store that with each account. Then we can use that id to query for the account for creating a validated user session.