Our development server at work is authenticated using client-side certificates that I install on every employee's computer (along with our Root CA cert). This takes me about 5 minutes to generate for them [1] and another 2 minutes to put into their OSX keychain. It's fun to sit there with each person and show them what I'm doing and how this wonderful system works.
But if I asked ANY ONE of them to do ANY step along the way, they'd throw their hands up and quit. My brother who is extremely tech competent can't do this. I like these suggestions but I just don't know fundamentally if this system can be used by people without a drastic overhaul to the UI.
It's even hard for those trying to understand it (I'll speak for myself coming from a non-CS background), and that's not even the same battle as implementing all the separate parts in an efficient way day to day. I've worked on my own bash cli tool[1] for more efficient openssl usage and mentioned it here before.[2] Only after that project was I able to finally understand the concepts enough to use the thing at all.
It's kind of a pain, but I wonder if you could, in whatever level of detail you would like to provide, walk us through the steps you take, especially the more 'throw their hands up and quit' ones.
I absolutely can. I know that project I listed has 0 documentation, but I should rip out the code and move it to another repo with a README.
The short of it is that I run the following. (I know this repo has our public keys, but if you clone it you can totally run this as well to see what's going on).
./bin/root-ca.sh
./bin/tls-ca.sh
./bin/client.sh
The first command will create the Root Certificate Authority in your tiered system. The second one will create a TLS Certificate Authority underneath the Root. This TLS CA is for issuing certificates (like browser client certificates, or email S/MIME certificates). Finally, the last script will walk you through creating one of these client certs.
The client.sh script will generate a .p12 file that you can import into Keychain or your browser's certificate store. The only other step is to import the Root certificate (mine is TeachBoostRootCA.crt in the ca folder) into Keychain and/or your browser.
If you're curious, take a look at the config file in the top level directory. This has all of the naming conventions my repo uses but if you clone this, clear the 'ca', 'certs', and 'crl' folders, then you can have free reign on running your own Certificate Authority. The scripts will walk you through everything but if you have any questions don't hesitate to open a GH issue on that repo and I'll get back to you there.
This is my observation as well. Smart people, e.g. people with PhDs or working on them, just by and large do not understand key pairs. They have terrible trouble with ssh keys, and I am sure would have as much or more trouble with client certificates.
It has to be something that is totally automated, and can't rely on copying or uploading or in any way touching public keys as a manual step.
Actually there's not a lot of work for browsers to do. Polish UI, make "logout" button, provide JS API, allow apps to handle errors better. Actually they should provide JS API to work with standard security cards and that will help to extinguish Java Applets from a lot of places. Not a lot of work, but it might start new era of web security.
I always wondered, why password-bases authentication is so prevalent, when asymmetric cryptography is there and actually used under the hood. That's a dream: one key to rule them all and no security problems with leaked accounts, unified UI to register, login, logout.
Why stop at one key? Personally I'd generate separate keys for all sites, just like I generate separate SSH keys. Apart from the obvious security benefit, it also means that your identities on different sites can't be tied together solely by your public keys, which companies could plausibly be convinced to share with governments, other organizations, or even individuals. (They're "public" after all, right?)
I would use one key for most websites, as I use one login for most websites, because that's not something I'm trying to hide and I like the convenience and simplicity. But of course it must be possible to use multiple keys.
Right, but it would be very difficult to put forward the case that a company should provide you with passwords, email addresses, or physical addresses. It's recognised that these are all private and personal information, because they're used for other purposes.
Your public key, however, would have one purpose and one purpose only - to identify you. As the public half of an asymmetric crypto pair, and given that people share their public keys on keyservers and on webpages all the time, it wouldn't be too difficult to convince an organisation that wasn't aware of the issues to give you the public keys associated with their accounts.
With that information, it would be really easy to definitively tie your identities together because you only need the public key in order to do so. Very few other pieces of information taken in solitude can do that - names are not unique, passwords are not unique, even physical addresses are not unique. (I'll grant that email addresses might be, but even then, companies aren't going to hand out email addresses to anyone who asks because of spam.)
There's a fundamental problem with client certs as currently implemented in browsers as well as the <keygen> tag: these certificates aren't origin-bound and violate the same-origin policy.
The method of authorizing client certs without using the same-origin policy is the source of the horrible UX problems: ask the user (often without a "remember this choice" checkbox, so users were asked every session)! Determining which certificate to use can be difficult depending on the subject/issuer, and in general this is a terrible choice to ask a user to make.
The problem gets a lot easier if you use origin-bound certificates:
With origin-bound certs there's a clear and unambiguous answer as to what cert to use for a given origin by-design. These certs can either be dynamically provisioned in a browser or device-locked to e.g. a Yubikey U2F token. There's no need to ask the user anything more than to push the button on their hardware token if they have one. Otherwise the process is completely automatic.
I really don't think efforts to use in-browser client cert authentication that don't respect the same-origin policy are going to get anywhere because of this problem.
If this has to take off, even with browsers providing an easier UI to create and manage client side certificates, two things would be important to avoid confusing users and a lot of "<insert browser name here> is crap and broke my login" messages:
1. Easy sync of the certificates across devices (as mentioned in the article, allow the user to choose which ones to sync). Most (non-tech-savvy) people still don't use password managers, and instead remember or write down passwords. You have to make it easy for these people to use multiple devices without having to jump through hoops. Even private keys protected by a passphrase/password add one more barrier (assuming each user has a separate OS account and is logged in). How would a user setup a new device with a previously setup client certificate? What fallback mechanisms (other than form based user/password auth) would be required for cases where a user wants to use a public computer or a shared computer account?
2. Handling the reissue of client side certificates for the expiring/expired ones along with revocation (if/when necessary). I believe this is a huge topic by itself on both the usability and security fronts. What would be the sweet spots for the expiry enforced for a particular site? Six months? One year? Two years? Ten years? Considering that most users in the current form based authentication scheme rarely change passwords, the convenience, or rather, the reduction in annoyance to end users, should be an important consideration.
I have seen client side certificates used in corporate environments where the management of these is easier, but even in those cases I have always seen alternatives like form based authentication available, along with other things like NTLM, etc.
Please comment/inform if any/what prior work has been done in these areas (I'm sure many people must have thought about these).
Regarding device synchronization, I wonder if having per-device certificates with something similar to 2FA, where you have to confirm the new certificate on a device with an already-trusted certificate, wouldn't be a better option. This would make revocation in case of a lost device easier (i.e. your other devices would continue working, no need to fall back to some other authentication method).
Back in 2008 I have blogged (http://pilif.github.io/2008/05/why-is-nobody-using-ssl-clien...) about client certs. The UI around them is horrendous and they also serve as a very good solution to uniquely identify clients across sites. This was a good idea, but in its current implementation it's unusable.
I agree as far as unsupported consumers are concerned, but it is perfectly usable in a corporate setting. As commenter mikegioia already noted; it takes only five minutes to help install the certificate on a user's computer. After that it just works.
One problem is that keygen is either deprecated or not supported. So you have to create the client cert on the server, then have the user download it (including private key). Or the client has to create a signing request and then upload it to the server, and then download the certificate.
Once that is done though, client certificates works pretty well, the browser will pop up a "what certificate to use" dialog when entering the web site. And the server (nginx) will send all the details like name, city etc to the web-server application.
Another problem vs passwords, is that the user has to copy or download the certificate to each computer device. And just like passwords, you need to have a process for identifying the user in case he lose the certificate/key.
I've used the HTML5 <keygen> element in Chrome and Firefox with great results. Chrome (on a Chromebook) even stored the generate key in the TPM on the device
I believe z3t4's point is that the element is deprecated after HTML5, so you can't rely on it working forever, or gaining adoption in new browsers that don't already have it.
Mobile browsers/devices handle client certs better than any desktop I've seen. Especially since they have hw trusted storage.
The issue is identity/linkage. If they let you set up an arbitrary number of keys, so you could do one per site, that's fine (and really, if you use the same username everywhere it's sort of the same thing)
Good set of recommendations. Client-side certificates are great for securing web applications in a corporate setting, but the client-side is indeed a bit rough in the UI — although once set-up, it is no hassle at all.
A major benefit of client-side certificates, is that you can increase the security of all internet-facing web applications you have by routing all external traffic through a gateway proxy, and performing the certificate check there. We use Nginx for that, and host applications such as GitLab, MatterMost, OwnCloud, and DokuWiki that way (performing authentication with LDAP so users can log in with the same credentials on all services).
I'm not sure I agree with his suggestion of having the ability to automatically synchronize client-side certificates between devices. I would rather have that be a conscious (security) choice rather than an automatic feature.
Agreed on certificate synchronization... especially since a certificate isn't the same as an account, it's just a key for an account... Having each device have its' own cert allows you to disallow a specific device without disallowing all devices for a user account.
I have been trying to find a way to use the `<keygen>` tag in production for a very long time, but I am consistently thwarted by the browsers simply not supporting it well enough. Where does the generated private key go? How do I sign things with it again? It's never clear, and browser support is terribly inconsistent.
We're using client certs for some mobile sites. But it hasn't been an ideal experience. Has anybody else experienced a problem where Android prompts for selecting which cert to use for a given site every time? iOS seems to remember which one to use for a specific site, but Android prompts EVERY time. I can't tell if it's just something misconfigured, or if its just the behavior of the OS by design.
There's almost no point of client certs for consumers without smart cards. Malware can steal your certs. People lose them or delete them or don't sync them.
Can we not devise a system to use our existing bank cards (with chips on them) to store client certs too?
Interestingly, that's already kind of available in some countries. I live in Austria, where we have a system called Bürgerkarte which utilizes PKI. One of the supported options are ATM cards (others being public health insurance cards, mobile phones or "real" smart cards). Unfortunately, it's not very widely used and quite complicated to set up. This would definitely need to be an international effort to become viable.
This is interesting , to use cross device there needs to be a vault of some kind to share btw browser would it make sense to have a recommendation for that also , so it would be standardized ?
One approach is to issue one certificate per device per subject. The subject identifier could remain the same. If this approach is taken, revocation checking is critical -- you end up having a bunch of certificates that all claim to be the same subject, so you need to make sure any presented certificate is valid. However, while revocation checking is often problematic for clients, some of those issues are more easily managed on a sessile server.
But if I asked ANY ONE of them to do ANY step along the way, they'd throw their hands up and quit. My brother who is extremely tech competent can't do this. I like these suggestions but I just don't know fundamentally if this system can be used by people without a drastic overhaul to the UI.
[1] https://github.com/TeachBoost/pki