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 requirements
This 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.
Design
I 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 things
- Ensure 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 userid
- the 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.
Update
Let 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.