I understand PKI reasonably well from a conceptual point of view - i.e. private keys/public keys - the math behind them, use of hash & encryption to sign a certificate, Digital Signing of Transactions or Documents etc. I have also worked on projects where openssl C libraries were used with certs for securing communication and authentication. I am also extremely familiar with openssl command line tools.However, I have very little experience with web based PKI enabled projects & hence I am trying to design and code a personal project for understanding this better.The requirementsThis is the website for a bank. All Internet Banking users are allowed use any certificate issued by a few known CAs (verisign, Thawte, entrust etc). The Bank is not responsible for procuring certificates for the user. These certificates will be used for authentication to the banks website. The platforms/OS etc are still not fixed.DesignI was wondering what's the best way to do authentication.I saw that Apache has a way to enable 2 way ssl - in this case, i think navigating to the website would automatically ask for a cert from the user. But I am not sure if this is enough because it seems that all it verifies is whether a certificate is signed by a trusted CA & also may be whether it falls in a white list of subject lines of the certificates etc. But this is not enough for a bank case because you need to be able to associate a bankuserid with a certificate.IIS seems to have a way by which I can have a certificate stored for each user in Active Directory. This is what I understood from reading few MSDN articles. You turn on 2 way SSL in IIS & then when the user tries to navigate to the website, IIS will send a request to the browser with a list of approved CAs and browser will let the user pick an appropriate certificate from his certstore and sends it to backend. I am assuming that IIS will do 2 thingsEnsure that the user has the private key corresponding to the cert (by under the cover negotiations)Based on the AD User-Cert Mapping, IIS will report the username to the application.Do the authentication explicity by calling crypto functions rather depending on depending on the webserver to do it.Show a user screen where he uploads a certificate and the application ensures the user has the private key corresponding to the cert (by asking the front-end to sign some string using the cert).The application has a database some of data is stored which allows each user to be mapped to his userid. This may be the whole cert corresponding to each useridthe CA and cert serial number corresponding to each user id.I was wondering which is the commonly used method? What are the best practices?If I should go with #3, what are the best ways to do this?Something which can also easily work with smartphone apps will be an added bonus.UpdateLet me clarify my statement code the authentication part myself because some of the answers seem to indicate that it has been misunderstood - my bad for not being clear.This doesn't mean I write crypto stuff myself. It just means I will actually call crypto routines explicitly instead of depending on IIS or any other webserver do it implicitly.
Web Authentication using PKI Certs
authentication
While I really wanted to answer issue by issue, I think I'll hit this topic by topic:Authorization/AuthenticationOK, first things first.  For your example, you need both:Authentication - proof that the user is who he says he is.  You've choosen PKI, with the implied proof of private key as your authentication.  Authorization - connection of the user to what he is allowed to do. This is the connection point between logging in and getting access to the allowed accounts.  The mapping of certificate to account and account access capabilities is the authorization.Authorization-wise, you have the problem of figuring out the process by which you connect your user's subject DN to their bank account.  Given the gravity of the transaction, you definitely want to have a strong process for this, and there is no single right way here.  You'd have to consult with the bank, and probably it's lawyers, to figure out how to do this in accordance with policy.SSL, Client/Server Authentication, Proof of Private KeyThe SSL protocol always includes server authentication, with an additional optional setting for client side authorization.  You are right with #1 in that Apache offers a setting that adds Client Authentication by PKI, and you can provision it with a list of trusted CAs.  During the setup of an SSL session that requires Client Authentication via PKI - you will get a proof of private key.Either option #1 or option #2 will provide this - both Apache and IIS can be configured this way.  Best practice wise, I'd take either one over rolling your own solution.  #3 comes periliously close to the don't write your own crypto rule.  Assuming that you can tie your transaction to the presence of an authenticated SSL session, there is no reason to roll your own.Also - in either option #1 or option #2, there is a way to get your hands on the whole certificate, and from there, to any part of the certificate.  Typically Subject DN and/or certificate serial number are used to determine the user's identity for authorization purposes.In terms of common usage - all major web servers are pretty common.  IIS, Apache, Tomcat, and many others can be configured with client auth SSL.  The decision from there is largely based on overall implementation.  The major web servers have all had ways to get access to the certificate provided in the SSL session, which is what you need for more detailed verification.Certificate Verification Add OnsAt a minimum, you'll need to:setup an SSL sessionpull the certificate (most web server's will check the certicate's signature and proof of private key)verify the certificate's validity date (not a given with any webserver)perform the authorization check for which accounts this certificate can accessGiven the high stakes of banking, you may also want to verify the certificate's revocation status - if the user's private key is lost or stolen, their certificate should be revoked.IIS may have the hooks for an OCSP or CRL verification - it tends to be a more comprehensive (hand holding!) type of system, but I don't remember off the top of my head.  I also don't remember if it's going to force you to use Microsoft products for this.  For Apache, you would almost certainly have to code or add on an OCSP/CRL check.  I believe it has hooks during SSL session establishment - usually this check performed once when the SSL session is set up.AuthorizationOn #1 vs. #2 - you're right that IIS has some built in functionality that'll tie the cert provided in the SSL session to an AD repository.  It's one of the cases where Microsoft goes the extra mile to make it easy to buy and use more of it's products. :)  There are nuances to how IIS ties into AD that are beyond the scope of this question and beyond my immediate recollection.  I've done some pretty crazy stuff with IIS and AD, and my general thought is that while you are doing something as relatively simple as pulling the username based on the certificate from an AD repository - you're probably fine.  It's when you get into more complex issues of data storage, odd AD lookups, and particularly crazy (but legitimate) things with PKI, you'll find that the excessive handholding provided by IIS is more like hand cuffs than a helping hand.With IIS, even still - you'll need something added to your AD structure, or somewhere else, tying the username to the bank account.  Typically in banking, a user has multiple accounts.  And 2 users can have a joint account, so this is a many to many relationship.For #1 - yep, you need to write your own lookup.  You need to code:- a database or LDAP hierarchy connecting the certificate to the user and the user to the user bank accounts.  The guaranteed unique part of a certificate is serial number + issuer DN.  Often Subject DN will work, but its not guaranteed in all PKI systems.That's typically how developers using PKI for high end authentication with Apache do it.  Having worked in a number of these systems, I have yet to encounter a case of easy authorization reuse, so I never really see it as a huge minus - I'm going to have to have something specialized either way, as roles/privileges are never easy.This sounds like a mix of #1 and #3 - my strong advice would be - use the native capabilities of whatever application/web server you use to generate the SSL session.  That'll let the browser to server setup with the certificate query take place in the standard, best practice, way.  From there, with Apache, you'll need to roll you own authorization system.  IIS will provide Microsoft's idea of how this should work for you. Known GotchasDo a bunch of browser testing.  From year to year, browser to browser, I find gotchas with SSL session handling.  Correctly chaining the SSL session to the series of web page requests and making sure that logout is handled correctly are the biggest areas of concern.  And it's got a lot to do with both the server and the browser software.  SSL is stable enough that when it works, it usually works, although there can be IE vs. everyone else issues.  In particular, the last time I did this, the question of force coding and session time out was a big deal. Smart PhonesGood.  Luck.  is about all I can say. I'm not at all a mobile app developer, but my impression thus far is that in the average smart phone, PKI cert handling is sub par or non-existant.I would so love to be proven wrong.  