This idea is based heavily on Kerberos, except it is expanded to include multiple networks. This system will allow single sign-on for a user interacting with a variety of services across the internet. It provides for a single identity that can identify that user everywhere.
This is not an active proposal. I am just trying to think things out.
The Universal ID looks like an email address (but doesn't have to be.) It is of the form:
'User' can be anything reasonable, encoded using URI encoding. The domain is any domain, encoded with URI encoding as well.
Your user ID is semi-private. You only share it with people you know or you want to identify you. This means, however, that two of your friends can get together and compare notes. This may be good or bad, depending on whether those two people are your friends and whether you trust them.
You should be able to create new, distinguishable identities to hand to people you don't trust, or to keep your circles of trust distinguishable. For instance, you don't want your friends to know which accounts are yours at the bank, although you may want the bank to know that you've introduced yourself as so-and-so to your friends.
The user@domain paradigm is perfect for this. You can arbitrarily create new identities at different domains. It's up to each domain to maintain whatever standard they like.
I first need to talk to my id services, wherever they may be. Once I've authenticated with them, through whatever method, I can ask for ID certificates for any domain.
An ID certificate has my ID (minus the domain) and the expiration date of the certificate all encrypted with the domain's private key. The matching public key that can decode the certificate is published through DNS.
I send a message out to bank.example:
me to bank.example: Hi, I'm firstname.lastname@example.org. bank.example to abc.example: Can I get jonathan's public key? abc.example to bank.example: Sure. Here it is. By the way, this key is only good for a short time. bank.example to me: <a secret encoded by the public key> me to abc.example: Hi. it's me. Can I get the private key so I can talk with bank.example? abc.example: Prove that you're jonathan by showing you have the ultimate credentials. me to abc.example: Ok, here's the proof. abc.example: Here's the key. me to bank.example: I've decoded that message with my temporary private key, here's the secret.
- Upon thinking further, I think what I need are simply secure communication channels, which rely solely on distributing keys. We simply need a secure protocol for the distribution of public keys. There also needs to be a third party that can vouch for the domains in question.
bank.example makes a DNS request, or relies on its cache, to find the public key for abc.example ID services. Obtaining them, it decrypts the certificate and finds out I am jonathan. It checks that the expiration time hasn't passed. It also checks that the expiration time isn't set to too far in the future. If these are satisfied, then bank.example.com accepts me as email@example.com
Several error conditions can occur:
- The certificate isn't for a user from the attested domain. In this case, the certificate isn't accepted. No further checking is necessary.
- The certificate has expired. In this case, no further checking is necessary. Report to the client that the certificate has expired.
- The certificate is set to expire too far in the future. Report this to the client and fail.
After the bank accepts me, it can give me a token to identify who I am. This can be used until it expires, at which point it can ask for another certificate.
There are three steps:
- Obtaining a certificate
- Providing the certificate
- Checking the certificate
Let's address these one at a time.
Obtaining a Certificate
The user provides credentials to the ID server and receives a certificate. This ID server can use a variety of verification methods. How the user knows which ID server to use and how is outside this specification. Suggestions include a simple password authentication, or a method of authentication involving two-way passwords.
A browser plugin can be written to authenticate the user when needed.
Providing a certificate
To provide a certificate, the user must enter in the certificate obtained into the correct field. This is a string of text that looks like:
A browser plugin can be written to identify form fields in HTML pages and either automatically fill them in or ask the user if it should do so. If the user hasn't authenticated, it can ask the user to do so at that time.
Checking the certificate
The service accepts the domain and certificate pair and then decrypts it with the public key for the service. How does it obtain the key?
It looks in the DNS records for abc.example for a UID public key. Obtaining one, it decodes the accompanying message. It checks the expiration time and also the username in the decrypted message.
Storing Keys in DNS
DNS seems like a good method for storing keys. But you can also use DNS to refer to the URL for a key and a revokation list.
Perhaps you can also use something like SSL, where you present a signed key along with the certificate.
Authenticating the Service
You can check that the service is allowed to do what it does by doing a reverse check.
Matching UIDs Across Domains
If you want to prevent two separate services matching you through your username, you can have your authenticating server provide you with a unique certificate for each of the domains with a unique username. It can generate usernames for you. For instance, to first-bank.example, I can send the username "FBsg23a". To second-bank.example, I can send username "eJkafd89". My ID server can keep my real username -- jonathan -- and then remember that FBsg23a is the name I use with first-bank.example, and eJkafd89 is the name I use with second-bank.example. It can provide me with those certificates when I ask for them.