best practices for secret_handle and secret?

Paul Crowley 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 
returning.

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
/\__/ http://www.ciphergoth.org/


More information about the yadis mailing list