best practices for secret_handle and secret?
paul at ciphergoth.org
Wed Jun 8 01:29:57 PDT 2005
Aren't timezones wonderful. If you wait until the evening to reply to
this, I'll be in bed when you send it, and you won't get a reply until
this sort of time, when you'll be in bed...
Brad Fitzpatrick wrote:
> Question: should I sign my $nonce in my $handle? Is there any
> cryptographic harm in letting users pass me any nonce in that handle,
> which I'd then use as the key in HMAC-SHA1 to sign responses? Perhaps
> they'd do it to exploit weaknesses in SHA1 and use different values to
> eventually derive the server-side secret value $secret?
I don't think there's any point in worrying about that. If related-key
attacks against the MAC primitive become a worry, well, that's why we
have a mechanism for supporting different MAC primitives. Because we
use HMAC for generating the MAC secret, the nonce is hashed no less than
four times before the consumer gets to see it. Pushing an attack
through that would be quite a trick.
You'll need to use hmac_sha1 not hmac_sha1_hex if you're going to XOR
the result with a hash of a DH shared secret.
Don't the answers returned by LJ::get_secret() have expiry times? You
should use those to determine the expiry time of the secret you're
I forgot to add a useful field to the get_authkey reply structure:
"replace_after". This is a time before the expiry time when you would
be wise to replace the secret that you're using; it helps ensure that
consumers use long-lifespan secrets, and thus can treat the tokens they
receive as valid for longer. There are no MUST bits in the standard
connected to this field, only SHOULDs.
Another thing that would be good would be if LJ::get_secret took a
parameter to determine what "pool" to get the secret from, so different
secrets were used for OpenID than for sausage attack prevention, and so
that each MAC scheme had its own pool of secrets. But you can certainly
put off doing that for now.
A couple of coding notes - but I recognise that your Perl experience way
outstrips mine by now so feel free to ignore.
Net::OpenID::Server now has quite a few callbacks, and I suspect it may
gain more. Would it be simpler to make it more like an "abstract base
class", and to provide the callbacks by inheriting from it and providing
implementations for some methods?
Given that, "secret_maker" could be made part of Net::OpenID::Server
since it's something all implementations might need, and it could call
out to methods which get the server secret. After all, people can
override it if they want to use something different.
I envisage two methods; LJ would implement them using LJ::get_secret
($secret, $expiry, $sid) = $self->get_current_server_secret($pool);
($secret, $expiry) = $self->get_server_secret($pool, $sid);
with "$expiry" in seconds since the epoch, probably ignoring the "$pool"
argument in the first implementation. From which you can use the code
in secret_maker to implement
($secret, $expiry, $sid) = $self->get_new_secret($pool);
($secret, $expiry) = $self->get_secret($pool, $sid);
the difference between these two is that "get_new_secret" returns a new
secret every time you call it.
\/ o\ Paul Crowley, paul at ciphergoth.org
More information about the yadis