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