Improving OpenIDs use of cryptography 1 - using a MAC

Nathan D. Bowen nbowen+yadis at
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 

Let's say my OpenID consumer has found the openid.server tag on Jim's 
blog page. The URL specified there is "". My OpenID 
consumer will:

    1) Resolve "" to
        Assumption: this name resolution was legitimate, not spoofed

    2) Contact and request a key
        Assumption: my connection truly is between me and, not 
between me and a malicious man-in-the-middle

    3) Verify that claimed identities really did come from 
"" 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, 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, 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 

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