New spec is unclear on HMAC digest type
Kristopher Tate
kris at bbridgetech.com
Mon Jun 27 19:35:17 PDT 2005
Hello everyone,
Upon implementing OpenID today, I became frustrated on building an hmac
sig. Took me going to another project in Python before I realized that
the OpenID spec is a binary digest (20-byte) instead hex (40-byte).
This is pretty unclear in the spec, only leaving one to realize that
it's binary because the spec requires it to be sent in base64.
Here's some code in PHP and Python to correctly implement
base64(HMAC(secret,token)):
PHP:
> //Calculate HMAC-SHA1 according to RFC2104
> // http://www.ietf.org/rfc/rfc2104.txt
> function hmacsha1($key,$data, $hex = false) {
> $blocksize=64;
> $hashfunc='sha1';
> if (strlen($key)>$blocksize)
> $key=pack('H*', $hashfunc($key));
> $key=str_pad($key,$blocksize,chr(0x00));
> $ipad=str_repeat(chr(0x36),$blocksize);
> $opad=str_repeat(chr(0x5c),$blocksize);
> $hmac =
> pack('H*',$hashfunc(($key^$opad).pack('H*',$hashfunc(($key^$ipad).$data
> ))));
> if ($hex == false) {
> return $hmac;
> }else{
> return bin2hex($hmac);
> }
> }
> //generate base64 encoded HMAC from $secret and $token
> base64_encode(hmacsha1($secret,$token))
Python:
> import base64, sha, hmac
>
> def b64(b):
> "String b as base64; without newlines"
> return base64.encodestring(b).replace("\n", "")
>
> #SIGN TOKEN WITH SECRET
> b64(hmac.new(secret, token, sha).digest()
Hope this helps!
-Kris
(God I love Python!)
More information about the yadis
mailing list