9

I've been thinking about using client certificates for my web apps, desperately hoping for security-conscious users to put their private key on HSMs so they don't get stolen even if the machine is compromised, and the added benefit of completely forgetting the login page is also nice (the user would be logged in from the first request as long as the client cert is presented).

However, from what I have read it seems so complicated to implement and I'm completely lost (I'm quite ashamed of asking such a newbie question).

Should I really be operating a PKI and issuing the certs myself? If every site does this, users would have an entire folder full of different certs, which is the equivalent of a passwords.txt in terms of usability. Even if everyone (ie. the rare sites that do use client certs) does it, I'd like to avoid adding yet another cert in that directory if possible, and let users reuse certs they already have, if any.

Is there a way of making them behave just like SSH keys, the user presents any key during signup and that key is bound to the account?

About verifying them in my app, most documentation I've found makes the web server check the certs against a CA (my own CA in this case, which brings us back to the PKI problem) and setting an environment variable if the cert is trusted ... that wouldn't work in my case as I'd like to get rid of the CA and have the clients provide their own certs, so based on the fact that I can't rely on checking them against a CA, what can I check them against? Do client certs have the equivalent of the SSH public key I can just store in my DB and check against that?

Finally, how would a new customer go about signing up to my website; he's asked to present a cert and he doesn't have any, how does he generate one?

  • How is that "the equivalent of a `passwords.txt` but with even worse usability"? The certs can be completely public. –  Feb 17 '15 at 01:08
  • @RickyDemer oh sorry, I meant a folder with private keys, but now that I think of it you can have multiple certs for a single key. –  Feb 17 '15 at 01:11
  • 2
    Client certificates can provide much better UI then a `passwords.txt` file -- the server can send a list of authorized CAs for the client cert, and the browser can then only offer the user a choice of certificates signed by those CAs. If the server sends itself as the only CA allowed, then the browser will only offer the user the certificate from that site -- more like a password manager than `passwords.txt` – cpast Mar 22 '15 at 18:51
  • 1
    Avec you considered looking at other tech? OpenId for example... – ALOToverflow Mar 23 '15 at 13:43
  • I awarded the bounty however I'm still looking for an answer to my very last phrase, ie. how does someone without a private key nor cert signs up on my website ? What should I do to make the browser generate a new key ? –  Mar 26 '15 at 14:02

6 Answers6

3

Edit: I realise that this may not be clear from the answer below... but from the point of view of your application, it doesn't really make any difference whether you run the PKI/CA yourself or whether you use one or more third-party CAs. Even if you choose to run your own PKI, you really don't want to code it yourself - so you'd use one of the existing ones, which would be logically separate from the application, and any interaction with the CA would be via the usual protocols. End of edit

Should I really be operating a PKI and issuing the certs myself?

As a general rule, unless you already know how to run a PKI, you shouldn't be doing it. It's a lot more complicated than you'd think, and a lot more ways that things can go wrong. Even companies that do PKI as their core business get it wrong sometimes; see Diginotar who had their certificate infrastructure hacked and eventually went bankrupt.

Allowing third-party certificates, especially by multiple CAs, has its own pitfalls. I have a smartcard that contains my electronic ID that I use to access my bank and several government sites. But I might also have a "soft" certificate that I use to access other things. If your site would accept both those certificate authorities, would you have any way to know that those two certificates refer to the same person (or user)? Would you want to have one user per certificate, or would you want one user to be able to use more than one certificate? What happens when a certificate expires - how would you know that my new certificate still refers to me? These questions need to be considered carefully when you design your applications and chains of trust.

Is there a way of making them behave just like SSH keys, the user presents any key during signup and that key is bound to the account?

This is just a Small Matter Of Programming... (In other words, not so small, but not impossible.) You'd probably want some way for the user to add/remove certificates, too.

About verifying them in my app, most documentation I've found makes the web server check the certs against a CA (my own CA in this case, which brings us back to the PKI problem) and setting an environment variable if the cert is trusted ... that wouldn't work in my case as I'd like to get rid of the CA and have the clients provide their own certs, so based on the fact that I can't rely on checking them against a CA, what can I check them against? Do client certs have the equivalent of the SSH public key I can just store in my DB and check against that?

You wouldn't save the entire certificate, you'd just save enough information that you can verify the certificate the next time the user presents it. This would usually be the certificate serial number, the CN and the issuing CA. You might also want to store the expiry date, so that you can remind users to renew their certificates before they expire. (This could of course be done when you check their certificates at login time, but it might be wise to store the data so you can email a reminder in case they don't login during the time they would have got the warning.)

Even when a certificate is issued by a third-party CA, the certificate will contain information about how you can verify its validity. This will usually be by OCSP (Online Certificate Status Protocol), which is a real-time check against the issuing CA's database. There's also CRL, a Certificate Revocation List, which contains information on which certificates are revoked by the CA. This is not real-time; the CRL will be re-issued at intervals.

Finally, how would a new customer go about signing up to my website; he's asked to present a cert and he doesn't have any, how does he generate one?

If you choose to use third-party CAs, you should give them a link to one or more of the CAs you trust.

If you run your own CA, you'd give them a link to that CA, which would have to be configured to allow (previously) anonymous users, as well as existing users, to request a new certificate.

Finally, if you want to have a look at setting up a PKI, you could try out EJBCA, an open-source CA/VA. It will give you a basic idea of the complexities involved.

Jenny D
  • 1,197
  • 9
  • 18
2

I work for a penetration testing company that requires a client certificate to log into any of our testing hosts. The certificates do require you enter a pass phrase when authenticating. This is done as an added layer of security, not to replace the need for passwords. If the certificate does not require a pass phrase, then yes - letting someone get a hold of the key is just as bad as giving them your credentials.

HillBillyHacker
  • 314
  • 1
  • 9
  • If it's not for security, at least it's for convenience. It's one less password to put in my password manager and being logged in automatically is also nice. –  Mar 25 '15 at 13:48
1

Both the goal and the approach are rather questionable.

Users don't have HSMs in their PC (unless you're all working at a very special company which somehow provides its employees with crypto hardware). At best, you'll encounter a user with a smartcard, but even then they probably won't use the card for your site, because it's just too cumbersome. A more realistic assumption is that users simply keep the private keys on their HDD, either with a weak passphrase or no passphrase at all. So if the PC gets compromised, the key does get compromised. That doesn't mean public-key authentication is useless, but your assumptions seem to be overly optimistic.

Client certificates don't eliminate the need for a log-in mechanism either. The browser will ask the user to choose a certificate and enter the passphrase, which is not really different from a standard log-in form (just uglier). At the same time, your users now have to worry about backing up their key and certificate, they possibly have to find a way to safely carry them to a different machine, and they need to get a new certificate if the key is lost or compromised. So it's actually more work.

I also disagree with your approach. The public-key cryptography of HTTPS is based on a very specific trust model, namely an X.509 infrastructure with hiearchical CAs. You may prefer a different model, but that's how the protocol works, and that's how it's implemented by all relevant servers and clients. Trying to “hack” the certificate validation will likely end in a disaster (as some of the previous answers show). So, no, there's no easy way out.

If you're hoping for client certificates to be both super-secure and super-convenient, you'll be disappointed. They're not. While they can be more secure than passwords, this comes at a price: more work for you, more work for your users, and much more complexity for your application.

Fleche
  • 4,024
  • 1
  • 17
  • 20
  • If not for security at least it's for convenience, and my browser prompting for a cert is easier to use than bringing up the password manager, unlocking it, etc. About the smartcards, of course it depends on the user, but at least I want to give them the possibility of securing their account *if they want to* and if they feel they have sensitive info on their account. –  Mar 25 '15 at 13:51
0

A self signed cert will effectively work as a SSH public key. You will have to add each users certificate to your list of trusted CA's. If a user does not have a cert already, you can create it using java script in the browser during sign up. You can ask the user to store their private key certs encrypted with strong passwords so it is not exactly the same as having a plain text password.txt. The private certs will be encrypted and stored and can only be unlocked with the password. When the website/webapp wants to authenticate, you will look for(or have the user select the appropriate private cert, which is a usability issue) the corresponding cert and the user will be prompted to enter their password for the private cert to be used.

Raghu
  • 351
  • 3
  • 9
  • 2
    I have to add there are tons of complications that you will face with this method of authenticating! A quick google for using self signed certs for client authentication should give you great resources of the potential pitfalls and also why it might actually work. – Raghu Feb 17 '15 at 00:57
  • Self signed certs are way of pretending you are in compliance. It's a false reality. – Citizen Mar 20 '15 at 08:58
  • Turning all users into CAs is conceptually wrong and defeats the entire purpose of certificates, because now everybody can issue certificates for everybody. Nothing prevents user A from making themselves a certificate for user B. – Fleche Mar 21 '15 at 17:18
  • That's the point. This is a bad idea but if u still want to do it anyway this might be the way to do it. For al you know this might meet the security requirements of the system that the asker has proposed. This is why I even said in a comment there are a whole host of problems with Doing this. You are failing to understand that the user might have different security requirements than the conventional use of certificates. – Raghu Mar 22 '15 at 18:55
  • 1
    Impersonation and mitm is not an issue here because this is for a login system. If you lose your password there is no way to verify if it is the correct client. Same with certificates. Lose your certificate and you can impersonate . Certificates will stil be stronger than a 10 character password against a brute force attack on the client login system so it's not defeating the purpose. – Raghu Mar 22 '15 at 19:01
  • 1
    You don't understand, Raghu: Your suggestion provides no security *at all*. It doesn't meet *any* requirements. When you simply turn everybody into a trusted CA, then everybody can issue certificates for arbitrary users. This is like putting the user ID into a cookie where everbody can change it to “admin”. I hope we agree this is *not* how application security works. You also seem to be confused about public-key authentication itself: The certificate isn't secret at all. “Stealing” it doesn't get you anywhere. What's critical is the *private key* which is never transmitted. – Fleche Mar 24 '15 at 23:40
  • Your certificate is a pretty'd up public key, signed by a CA. If you sign it with your own private key, your certificate is a root certificate. This is what i meant by treating each user as a CA. If the server stores these root/self signed certificates, it can use it to authenticate the person with the corresponding private key. Ofcourse, if the person with a particular private key signs certificates for others, the only person who will be able to login will be the person with the private key. – Raghu Mar 26 '15 at 15:36
  • If you are signing other's certificates, it is like creating two accounts, with passwords(ie private key) for these accounts only with the signer of certificates. Think of this scheme as replacing user name and passwords with a private key, and the server, instead of storing hash of passwords or whatever they use to authenticate, being replaced with the self signed cert. – Raghu Mar 26 '15 at 15:36
  • Also, i mistype'd in one of my above comments. I meant private keys. " Impersonation and mitm is not an issue here because this is for a login system. If you lose your password there is no way to verify if it is the correct client. Same with private keys. Lose your private key and you can impersonate . private key + Certificates will still be stronger than a 10 character password against a brute force attack on the client login system so it's not defeating the purpose. " – Raghu Mar 26 '15 at 15:42
0

Is this really a good idea?

Yes, it could work, but... In case of a simple MITM attack, what will happen?

  1. Your server won't recognize hacker's client cert and will return to login page.
  2. The user will naturally re-enter his credential and so could work normally again.
  3. But from there, your server will accept hacker's cert, as long client don't try to connect again from elsewhere.
  4. Your security is compromised.

Of course, the second step is not a real evidence, but as social engineering stay the first way of security faults, You could not expect that your users have to care about!

  • MITM is out of the question as the site is obviously served over HTTPS, and if the user is stupid enough to accept an MITM's certificate then it's not my problem. And MITM is just as effective without a client cert, the certs will actually help mitigate it if I don't allow other means of authentication like login/password. –  Mar 22 '15 at 18:31
  • 1
    You **must** keep in mind *user is stupid enough*! And no: they could even be already hacked and mitm *authority* cert already pushed in his trusted list... The real problem is that your server will register *mitm client cert*! – F. Hauri - Give Up GitHub Mar 22 '15 at 19:55
-1

StartSSL provides free Class 1 Web server certificates (SSL/TLS) & Client and mail certificates (S/MIME). I use them for both my website and email. Verification is done automatically and your clients would often get the certificates almost instantly.

This is better than you operating a PKI and issuing the certificates yourself. You can check the client certificate against the StartSSL CA root certificate and validate the user on the app (This is how StartSSL PKI login works and it works seamlessly).

Having a third-party PKI also takes care of new customers who does not have any certs by automatically re-directing them through a proven certificate generation and key management authority like StartSSL.

P.S. I am in no way affiliated with StartCOM or StartSSL. I use their free services myself, so I'm just recommending them in this case.

Pavin Joseph
  • 706
  • 7
  • 10
  • 1
    Outsourcing the PKI work to a third party means that the entire authentication now depends on that third party. This is not just the usual risk of trusted CAs. It's more like giving them admin rights to your application, because they can in fact do whatever they want without performing any attacks. The standard validation procedure of CAs is also fairly laughable, whereas an internal CA can actually make sure that the user is legitimate. Of course a third-party PKI is more *convenient*, but this comes at the price of giving up a lot of security. – Fleche Mar 24 '15 at 23:57
  • 1
    Well, if you can't trust any CA, even the reputable ones and are qualified enough / have better resources than the third party CA then by all means you should set up your own PKI and CA. I honestly don't think that is the case here. And please elaborate your statement on "they can in fact do whatever they want without performing any attacks". – Pavin Joseph Mar 25 '15 at 12:45
  • Trusting a third-party is out of the question. By "they can do whatever they want", it means they can sign their own certificates which will be recognized as valid by my application, and thus impersonate users without anyone noticing. –  Mar 25 '15 at 13:52
  • @AndréDaniel If the third-party does in fact commit such fraud by impersonating users then you have a million dollar lawsuit for damages and fraud. I really can't believe DigiCert/Comodo/StartSSL would do any such thing. – Pavin Joseph Mar 25 '15 at 14:00
  • @Joseph a lawsuit doesn't make someone forget something they weren't intended to see. And what if the attacker is the government itself ? No lawsuit can protect from that. –  Mar 25 '15 at 15:15