Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

  1. 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.

  2. 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.
  3. 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.

share|improve this question

migrated from security.stackexchange.com Jun 11 '13 at 6:35

This question came from our site for Information security professionals.

    
Related: security.stackexchange.com/questions/34897/… –  Adnan Jun 7 '13 at 12:35
    
@adnan - I have already written about "mutual SSL with Apache" in my question and why it wouldn't work for me. –  user93353 Jun 7 '13 at 12:41
1  
Why the downvotes? If the person can leave a comment as to what's wrong with the question - I can may be try to improve it. –  user93353 Jun 7 '13 at 12:56
    
Yes, I saw it. I'm not saying this is a duplicate, I'm just saying it's related. More information for the reader of your question. –  Adnan Jun 7 '13 at 12:57
    
@Adnan - OK - I was just worried people might look at the link and vote to close my question as a duplicate :-) –  user93353 Jun 7 '13 at 13:01
show 5 more comments

3 Answers

up vote 6 down vote accepted

While I really wanted to answer issue by issue, I think I'll hit this topic by topic:

Authorization/Authentication

OK, 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 Key

The 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 Ons

At a minimum, you'll need to:

  • setup an SSL session
  • pull 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 access

Given 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.

Authorization

On #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 Gotchas

Do 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 Phones

Good. 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.

share|improve this answer
add comment

Personal certificates work well for periodical renewal of certificates (which has quite a robust process behind it) and can be implemented as a "password-less" authentication that customers like

but where it fails is

  • The cost per certificate
  • compatibility with modern browsers
  • end users extracting certificates and storing private keys insecurely

be aware that modern personal certificates with sha-2 signing do not work with Safari on iPad and lots of modern browsers. This is because personal certificates never really took off like the certification authority organisations thought it might. Issuing 30,000 certificates (what we do) costs about the same per certificate as some hardware token types.

Your strategy to allow customers to find their own certificates is not really valid. It's hard to find suppliers of personal certificates nowadays and they are quite expensive - you need to ensure that the business case works otherwise customers will simply not buy into this.

share|improve this answer
    
` It's hard to find suppliers of personal certificates nowadays` - not in my country. People use certs for banking and also for filing tax returns electronically. So it's very easy to get it. I just gave examples of CAs like Thawte, Verisign so that people get that I am talking about external CAs. –  user93353 Jun 7 '13 at 15:49
    
+1 for mentioning user behaviour. –  Mayank Sharma Jun 7 '13 at 17:12
add comment

Okay, a lot going on here. First things first, client cert authentication is useless if it isn't supported on the endpoint. So, we have a great post from Intrepidus covering the basics of client authentication for smartphone apps.

Next, let me highly suggest you not code your own authentication routine. There are lots of great, vetted libraries that handle this. You'll save yourself functionality and security bugs by running with a mature library for auth. Using a vetted, mature library for this would definitely be best practice.

Next best practice is using a directory for handling your client:certificate mapping. So you'll be looking at AD or LDAP. As you mentioned, Windows and IIS makes this pretty seamless for you. IIS.net has a good rundown on configuring certificate mapping under IIS.

If you roll with Apache, this isn't as easy out of the box. It looks like mod_authz_ldap does client certificate mapping, but I've not personally worked with it.

So that brings us to the logistics of actually implementing something like this. You are not signing the users' certs, so you need an ironclad process for a user submitting their cert and having your app publish it into the directory. I would want to see two-factor for this, with a password auth and a text message or call to a trusted number. I would email the user to let them know that a cert was added to their account. I would let a user remove the user-cert mapping through their account management page in the app.

I would look at what Google and Facebook do for setting cookies for trusted devices to avoid two-factor. I would have new devices auth with two-factor before allowing certificate-only auth.

I would also think about how to handle user certs being revoked. This means checking an external certificate revocation list (CRL). What do you do if a client certificate doesn't have a CRL distribution point defined? Do you check the CRL whenever the user logs in, or on a scheduled basis as part of a job, since there will likely only be a handful of CRLs in use?

Really, this boils down to: how do I know I can trust that the users' certs have not been compromised, and how do I trust that I can map certificate X to user Y.

share|improve this answer
    
` First things first, client cert authentication is useless if it isn't supported on the endpoint.` - what does this mean? –  user93353 Jun 11 '13 at 2:48
    
Most of this answer address my question at all. I appreciate the effort taken to address side issues - but I am really interested in a more detailed answer of my actual question. I know OCSP/CRL has to be done - but it's not relevant to my question. How to do enrollment is not part of the question. –  user93353 Jun 11 '13 at 2:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.