best practices for secret_handle and secret?
Brad Fitzpatrick
brad at danga.com
Tue Jun 7 19:27:49 PDT 2005
Paul,
LiveJournal's currently (unreleased) use of the new Net::OpenID::Server is
as follows:
package LJ::OpenID;
use strict;
use Net::OpenID::Server 0.04;
use Digest::SHA1 qw(sha1 sha1_hex);
sub server {
my $get = shift;
return Net::OpenID::Server->new(
args => $get || {},
get_user => \&LJ::get_remote,
is_identity => sub {
my ($u, $ident) = @_;
return LJ::OpenID::is_identity($u, $ident, $get);
},
is_trusted => \&LJ::OpenID::is_trusted,
setup_url => "$LJ::SITEROOT/openid/approve.bml",
secret_maker => \&LJ::OpenID::secret_maker,
);
}
# Net::OpenID::Server callback that must return:
#
# ($handle, $secret, $expires)
#
sub secret_maker {
my ($time, $secret) = LJ::get_secret(); # $secret is server's secret key generated at $time
my $nonce = LJ::rand_chars(40);
my $handle = "$time:$nonce";
my $secret = hmac_sha1_hex($handle, $secret);
return ($handle, $secret, 86400 * 14);
}
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?
My gut feeling is yes, but I'd like confirmation.
In which case I'd do:
my $handle = "$time:$nonce:" . hmac_sha1_hex("$time:$nonce", $secret);
And on input, only accept handles that match the hmac. (thus ones
that I handed out...)
If either version looks fine, let me know and I'll build
LJ::get_secret() into the Net::OpenID::Server code, provided users
define callbacks for stable storage, getting/setting random data
($secret) given a $time.
Thanks,
Brad
More information about the yadis
mailing list