Improving OpenIDs use of cryptography 1 - using a MAC
Nathan D. Bowen
nbowen+yadis at andtonic.com
Thu Jun 2 13:09:23 PDT 2005
When I first read the HMAC idea last night, I was excited enough to
start reading up and making some sample Java code for myself, because I
was positive it was a great idea. Today, I was explaining the whole
thing to a co-worker, and when I tried to show him why the secret keys
were safe to send in cleartext, I talked myself out of it.
At first I was willing to question my knee jerk reaction to keep secret
keys protected, but after giving it a lot more thought, I can't see why
OpenID is the one case where we can all stop worrying about sending
unencrypted private keys over the internet.
I don't think it's as simple as a question of whether snooping or
spoofing is more difficult. Snooping may be difficult, but that doesn't
mean it's less "likely". As an attacker, I'd be more likely to bother
with snooping, difficult or not, based on how much incentive was there.
There's a lot of incentive to snoop a connection that contains a
plaintext secret key. Also, I'm not only concerned with the probability
of an attack -- I'm concerned with how "bad" it will be for me when one
finally happens.
Sorry for the length of what follows, but I lack the expertise and
vocabulary to be less verbose when it comes to some of this
security-related stuff. Maybe someone can tell me I'm misunderstanding
something or otherwise assuage my fears. If not, I'm going with my
cryptographic gut on this one, and suggesting that we continue to
protect our private keys whether or not we scrap our public keys.
In the current specification, the only thing that gets communicated
directly from server to consumer is the server's DSA public key. In the
new HMAC proposal, the server would instead be communicating a secret
key and a key ID. Here's an assessment of the consumer's actions and the
assumptions inherent therein, worded to be applicable to either
HMAC-SHA1 or DSA-SHA1.
Let's say my OpenID consumer has found the openid.server tag on Jim's
blog page. The URL specified there is "openid.blogorama.com". My OpenID
consumer will:
1) Resolve "openid.blogorama.com" to 1.2.3.4
Assumption: this name resolution was legitimate, not spoofed
2) Contact 1.2.3.4 and request a key
Assumption: my connection truly is between me and 1.2.3.4, not
between me and a malicious man-in-the-middle
3) Verify that claimed identities really did come from
"openid.blogorama.com" using the key retrieved above
Assumption: The secret key has not fallen into the wrong hands
If the secret key is compromised, all bets are off. If Jim has the
secret key, he might provide me with a valid signature or HMAC without
ever contacting openid.blogorama.com, and I'll think it really came from
the OpenID server. This would be very bad.
Many other things can go "wrong" in step 3, but they are precisely what
OpenID is designed to protect me against -- and it will, assuming the
secret key is safe:
1) If Jim doesn't really have a blogorama account,
openid.blogorama.com won't be willing to assert and sign his identity.
2) If Jim's got a DNS problem and thinks he's logging into blogorama
but really logs into some rogue phishing site, that phishing site won't
be able to generate a valid signature or HMAC, so I won't trust the
response.
and so on.
Step 3 is the important one in assessing these proposed changes, because
the biggest difference is whether or not we're foolish to assume that
the secret key is safe. In the current implementation, compromise of the
secret key is almost impossible, barring the compromise of the ID Server
itself. In the new implementation, I'm completely convinced that
compromise of the secret key is made *significantly* more likely than if
it were never sent in plain text.
So first of all, secret keys are more likely to be compromised if
they're sent unencrypted. Secondly, sniffing becomes more likely,
difficult or not, if there are secret keys to be sniffed. But let's also
consider the damage we'd suffer from these attacks in real life.
Spoofing Attacks:
If I sit in between a consumer and LiveJournal when the consumer asks
for a public key, I can give it a different public key -- one for which
I have the private counterpart. Then, the consumer will trust things
that I sign, believing that I am LiveJournal. But for this to work and
to go undetected for any length of time, I'd better be spoofing the
connections for all the user agents that are going to use that consumer
with a LiveJournal identity, or the consumer will notice that it's not
verifying any LiveJournal users today.
Secret-key Sniffing Attacks:
If I sit in between a consumer and LiveJournal when the consumer asks
for a secret key, I don't need to do anything active to interfere with
the exchange. I watch for the secret key and make a note of it. Then,
for as long as that secret key is good, I can forge LiveJournal
identities from anywhere I like.
I am interested in the benefits HMAC would offer to OpenID, but not if
we have to do it with our secret keys sent over unencrypted HTTP. We've
already reached a conensus about https being unwelcome in the OpenID
spec -- to get the benefits of the signed certs we'd either have to
centralize around our own CA or ask ID servers to spend money, and both
of those would be contrary to the design goals of OpenID. Something like
Diffie-Hellman would make me feel better about the secret key's safety
against sniffing, but a man-in-the-middle is still far more empowered to
do actual damage if he can sit in the middle of a private key exchange.
Am I way off base here, or is this a legitimate concern?
More information about the yadis
mailing list