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