In this post I describe what I think is a fundamental problem with OpenID, and how I think a decentralized authentication scheme should work to avoid this problem. I assume that you are familiar with OpenID, DNS, asymmetric crypto and X.509 client certificates. Just a refresher about the terminology: with OpenID, you log in at a relying party by specifying a URL, the relying party queries this URL to find out who is the provider, and the provider takes care of identification.
This post is not about the practical problems of getting people to understand and adopt OpenID. I do not intend to complain about the many websites where you can only log in with a closed list of proprietary providers and not with the OpenID URL of your choice even though it probably wouldn't be harder to support. I do not intend to complain about the fact that people don't get OpenID, or discuss whether the cause is OpenID's complexity or the general public's cluelessness. My complaint is about the core design of OpenID. It is the following:
OpenID uses URLs to identify people, and URLs rely on the DNS system.
Why is that bad?
- DNS is centralized
- If you are your OpenID provider, you need to get a domain name at a DNS registrar. This process costs money, and depends on the DNS system, which is centralized.
- URLs can change
- Do you want to change your OpenID URL? Well, do it at every relying party if they have an option for that. Want to do it globally? Well, you can't. So, you might get stuck paying for that old domain name forever after all.
- Domain names are reassigned
- If you accidentally let your domain name expire, then you are locked out of your accounts at relying parties. Worse, anyone can buy it. At which point, they get full control of your OpenID URL, and you have no way to stop them. Woops.
- DNS is insecure
- Securing DNS is an afterthought, so it's a bad idea to assume it's secure unless there's no better way.
It is true that the last two points can be mitigated if you instruct the relying party to use HTTPS (by indicating "https://" explicitly in your OpenID URL), and if you have an HTTPS certificate that relying parties will trust, and if an attacker doesn't (obviously, if a relying party accepts your server's self-signed HTTPS certificate, then it would gladly accept an attacker's).
To summarize: OpenID is decentralized but relies on a system (DNS) which is not very secure, centralized, and in which being your own provider requires you to commit to a domain name which you basically have to renew and pay for indefinitely. Hmm. Can we do better?
The fundamental principle of OpenID is that you provide the identifier of a resource (the URL) and prove that you control this resource. You actually exercise your control over the resource by having it point to an OpenID provider whom you trust to identify you in a suitable way, but the basic idea remains: to log in, you name something that you control.
It turns out that there are other resources that you can name and prove that you control, and that don't need to be registered in a centralized system like DNS. I'm thinking about public keys. You could provide your public key (or its fingerprint under a secure hash function) to relying parties, which would associate you to this public key (a URI of sorts) rather than associating you to a URL. You would then demonstrate ownership of the private part of this key when logging in. Problem solved. This is how ssh public-key authentication works, but this has also been applied to the web: X.509 client certificates work precisely like this. Sadly, no one uses them, because people do not want to generate keys and configure their browsers and such.
All hope is not lost, though. What about the following scheme:
- You give a URL to the relying party.
- This URL points to a document indicating both a public key and an OpenID provider which controls the associated private key.
- The provider demonstrates to the relying party that it owns the private key associated to the public key.
- You authenticate with the provider like in vanilla OpenID.
- The relying party does not associate your account with the URL you provided, but with the public key.
This indirection would change nothing for casual users who would just register with any OpenID provider and log in with their OpenID URL without caring at all about "their" key which would be entirely managed by their provider. The behavior of relying parties, and the interaction between relying parties and providers, would be different, but none of this would be visible to the user.
However, power users would own their key without being tied to a specific URL, and could configure an endpoint with this key at any domain of their choice. Benefits:
- If you want to change your domain name, just put the key at the new domain and identify with a URL at the new domain. The URL is just a pointer, the underlying key is still the same, so you're still the same person to the relying party even though the URL changed.
- If your domain name expires, no big deal, someone who buys it will not get your key, and you can just host the key elsewhere.
- If you want to stop being your own provider, just entrust your private key to an existing provider and you can start logging in with a URL pointing to this provider.
- If you are paranoid and do not trust DNS, it would be easy to extend the protocol a bit so that, when you give your URL, you can also optionally specify your public key to the relying party. In this case, the relying party would be required to check that the public key used by the provider matches the one you specified at login.
- If you don't want to have anything to do with DNS, there's nothing stopping you from using the IP of your server as URL. Hell, if you're not browsing from behind a firewall and your machine can accept incoming HTTP connections, you can have your key on your machine, and just give the IP of your machine -- you don't even need a server.
Hopefully I managed to convince you that identifying users (as opposed to locating their provider) using URLs is a bad idea. Of course, this point is not specifically targeted against OpenID. Mozilla Persona (aka. BrowserID) is using email addresses as identities, which also depend on DNS. I'm still looking for a decentralized authentication scheme which understands that you should just use URLs as pointers and use public keys as identifiers.
Addenum: It turns out that OpenID 2.0 is supposed to support XRIs which (according to the last paragraph of this section) can be used to mitigate the problems I'm talking about. However, after spending some time trying to understand what XRIs are and if someone is using them, I'm not convinced that it is really an elegant and practical way to solve this problem, so I think the point still stands.