Own JS/CSS options

Tuesday, March 13, 2012

Authenticating Users on the Web

One of the main challenges on the web right now is the question of authentication. Not so much the question how to do it at all, but how to make it easy and convenient.

Authentication and Authorization

The basic problem of authentication is figuring out whether the user who claims to be account23 today is the same user who claimed to be account23 yesterday. Once that is established, the user is authorized to actions based on what account23 is configured as.

Most authentication protocols try to authenticate within a specific domain. For example, X.509/SSL tries to authenticate the user as a person in the real world. OAuth on the other hand authenticates the user based on the domain of the service provide—using your Google account, you can authenticate yourself to any web service as a specific person on Google.

For most web services, though, domains outside of their own should be irrelevant. All they need is the ability to identify the user today as the same user as yesterday.

The classic username/password method enables just that. Users can create usernames and passwords to identify themselves, and those identify the users exclusively within the domain of this site. But usernames and passwords do not scale. Password reuse reduces security a lot, and memorizing dozens of different passwords is just not feasible.

That X.509 identifies users in the real world and that OAuth identifies users with respect to service providers is done for the purpose of authorizing these users based on their identity in those domains. It’s not just sufficient to identify the user as the same user as yesterday, the site also wants to find out who that user is in another domain. For example, to access specific services on the Google sites for that user. This can be necessary, but for the purposes of most websites, it isn’t.

The need to authorize users in addition to authenticating them adds a lot of complexity. OAuth is simple in concept, but it does not solve the problem of authentication. It only adds a third party and delegates the problem. Now the user needs to authenticate to that party instead to the web service itself. It’s not an authentication protocol, it’s an authentication delegation protocol. X.509 solves the problem of authentication, but to cover the real world domain, it adds an incredibly complicated stack of capabilities, Certificate Authorities and requirements.

Luckily, thought, we can use X.509 for pure authentication without all of that extra work.

Abusing X.509

The X.509 protocol, as baroque and cumbersome as it is, is widespread and widely supported. Re-using it for a better type of authentication would be very useful, as it gives us an existing (mostly) working infrastructure. And even though the concepts used for establishing the real world identity of users are quite deeply ingrained, it should be possible to work without them.

The basic part of an X.509 certificate is the RSA key. This is what we can use to identify a user. A key has an unique fingerprint, and that can function as the unique id for the user. A website can request the browser to generate a key, and store the fingerprint. From now on, when the browser connects to the site, the browser will simply identify itself with its key, and the site can uniquely identify that user.

There is no problem with generating any number of keys like this, so the method scales well. If a website also creates their own CA, the browser can even automatically select the right key without any user interaction. The user can securely authenticate herself without any further hassle.

Problems and Other Works

Leaves the question what to do with all the data you can (and have to) enter in the X.509 certificate. My suggestion would be to leave it all empty or filled with dummy values. It’s all irrelevant for our purpose.

The WebID protocol proposes something pretty much like this already. They do require an additional URL field linking to the user’s public profile, though, requiring users to have a public profile in the first place. For the purpose of authentication, that is not relevant and only adds complexity.

The benefit they get with the public profile is a kind of certificate revocation list. Once the certificate is not displayed on the public profile anymore, it’s invalid. This is useful, but we can live without, too. Should a key get compromised, the user has to disable it on the site she uses it on, just like what they do when they lose a password. Doing so should generate a new key.

In general, sites should allow multiple keys per account. This also enables users to register their mobile devices and to authenticate them with their main device.

The remaining tricky situation is the “I have lost access to my account” case. We rely all too much on e-mail as a fallback for these. But that’s a general problem and a bit beyond the scope of this text.

Finally, this whole idea needs to be tested and checked for a feasible implementation. I think it should work, but I have not tried yet.