Saturday, March 05, 2011

More on identity

Dave Winer wrote a blog post titled Using DNS as a thin ID system . I encourage you to go read it, but in essence his main gripe is that the current means of identifying a person online are too complicated.
And I agree, but with a caveat: there is clearly a need for a simple identification system, while the need for (and current existence of) more complex ID systems is also there.

Winer postulates that the DNS could be used for the simple ID system. Let's call it SID for short. Here again I have to agree he's on to something, since when we designed the .tel top level domain, that was a primary goal.
However, with .tel we started by the complicated stuff, implementing all the current stuff like OpenID et. al., and also implementing a unique, original encryption system for sharing private information inside the DNS zone itself.
So now in the spirit of bootstrapping and getting something up quickly, here's my implementation of Winer's SID:

http://passw0rd.henri.tel

Here's how it works:

  • Assume you don't know the above URL
  • I go to your site and want to authenticate myself
  • you ask me for my domain name (henri.tel) and password (passw0rd)
  • you look up password.domain
  • if you look up using DNS and it returns NXDOMAIN, then authentication failed
  • if you look up using HTTP and it returns 404, then authentication failed
That's about it.
Oh, one more thing: inside passw0rd.henri.tel there are a number of interesting records of type NAPTR that point to my different web properties. There are also TXT records that define my name and current work. If you're looking it up via HTTP, you'll get that info in the hCard of the resulting page.

All of this, today, is available to any .tel owner, without any need for knowledge of DNS or anything beyond knowing to uncheck the "create a link" box in the below screen:


That's all there is to it.

Now the purists will say that this identification system lacks much more than it provides. I agree. If you want OpenID, my henri.tel domain is an OpenID provider as well.
But here, we're looking for a dead simple way of knowing that the person is the same person who came last week. We don't want more than that, and I think Winer's SID is something worth trying out, especially since it's pretty much universally applicable across all top level domains. (I would only use domains, because they give you good legal control in case someone tries to impersonate you, etc...)

14 comments:

andy.tel said...

We don't want to send clear text passwords over the wire though, so perhaps (until DNSSEC is deployed) it would be better to hash the password.. still not secure, but at least as secure as Twitter! :)

andy.tel said...

I guess there'd also have to be a record denoting that the subdomain label is indeed secret. A TXT record perhaps.

Rik said...

Sure, doing the hash is better.
PKI encryption is even better. All doable today, it all depends on how far you want to take this.

Rik said...

You don't need anythink to say it's secret. Just don't link to it from anywhere. Keep it simple.

andy.tel said...

The problem is I already have subdomain labels that aren't secret. What would stop somebody from authenticating themselves as http://social.andy.tel, for example?

Rik said...

Ok, but let me up you one:
In the subdomain, you insert a "username" naptr record with the username you want for this "password".
Then the requestor can check that the username matches also the requested password.
You can add as many as you want, in the same password subdomain, of course. And you could hash them too, if you really wanted to.

andy.tel said...

Each FQDN is inherently a distinct username and password combination, e.g. only the username "andy.tel" (with the correct password) could resolve hashed-password.andy.tel.

I see it working like this:

1. I give the SID Consumer my username (andy.tel) and password (letmein).

2. Due to the maximum length of a domain being 255 octets the SID Consumer should salt and hash the subdomain label like this:

MD5(SHA256("andy.tel" + "letmein"))
=> "67b2327c3a72d7b2adb34775a856ff49"

3. The SID Consumer queries.

3.1. To authenticate the user:

$ dig 67b2327c3a72d7b2adb34775a856ff49.andy.tel txt

=> 67b2327c3a72d7b2adb34775a856ff49.andy.tel. 60 IN TXT "SID-authenticated"

3.2. To discover information about the authenticated user, follow a non-terminating NAPTR, if present:

$ dig 67b2327c3a72d7b2adb34775a856ff49.andy.tel naptr

=> 67b2327c3a72d7b2adb34775a856ff49.andy.tel. 60 IN NAPTR 100 100 "" "" "" andy.tel.

What do you think?

andy.tel said...

Better idea.. SIMPLIFY! Build the secrecy into the domain string:

$ dig 67b2327c3a72d7b2adb34775a856ff49._sid.andy.tel naptr

NXDOMAIN on a failure to authenticate, otherwise a NAPTR record MAY exist.

Rik said...

Why would you need to domain with the password to hash, when one already knows the domain? Would that make the hashing stronger or weaker? Honestly I'm not a crypto expert so I can't comment on that level.
Also you're drifiting a bit far from the "simple" id system.

andy.tel said...

It's better to salt the hash with something (the username) to prevent rainbow table attacks.

MD5 is too weak by itself, but we can't use SHA256 directly due to the maximum length of domains being 255 octets.

Even if somebody (an intermediary resolver, somebody listening to our traffic, etc.) knows the hash, they shouldn't be able to discover the real password from it.

Maybe there's a better way.. I'll think about it.

andy.tel said...

It turns out RSA published a Password-Based Key Derivation Function:

http://en.wikipedia.org/wiki/PBKDF2

Precisely what we need. It performs "key stretching" to compute a much stronger hash than my previous suggestion. Sounds complicated, but it's pretty simple to implement in a few lines of code.

Still, we're giving passwords to relying parties so I assume we're going to want to change them fairly frequently. I can imagine things like browser plugins helping us do this :)

Rik said...

PBKDF2 is a good idea, but it necessitates agreement in how to generate the hash: both the domain owner and the requestor need to generate the exact same hash with the exact same parameters. And that in the long term doesn't work so well for PBKDF2 because you'll want to increase iterations as CPU speed increases.

If you had versioning this would work, but again it keeps complicating things:

67b2327c3a72d7b2adb34775a856ff49-1.andy.tel

where "-1" states it's version 1 of the protocol, which would specify for example 10,000 iterations. Also the salt needs to be known by both, and therefore it'd be known by an attacker as well.

andy.tel said...

Yep, that's a good point.

But it doesn't matter that the salt is known by an attacker as well - the point is that we're forcing him to precompute rainbow tables to crack each hash he knows.. made even more difficult by the PBKDF2 function. Passwords are too weak to hash by themselves.

It's a hard problem to solve if you're going for simplicity at the same time. :)

andy.tel said...

Just to complete the idea, we could store the iteration parameter for PBKDF2 in another record, allowing the user to manage it.

I think there's a better solution using X.509 client certification. The downside is complexity, and browser implementations pretty much suck right now.