#! /usr/bin/perl -w

use strict;

##################################
## implémentation HMAC RFC 2104 ##
## jve - mai 2008		##
##################################

use Digest::SHA1 qw(sha1);
use Digest::MD5 qw(md5);
use MIME::Base64;

my ($K, $Kmd5,$Ksha1, $text, $Hmd5, $Hsha1); # 'K' the key, 'text' the data to compute the hmac on, 'H' the HMAC
my $B = 64; # block size in bytes
#print "\ninput HMAC key in base 64 form -> ";
#$K = <STDIN>;
#$K = chomp($K);
#$K = decode_base64($K);
$K = "Jefe";
print "Using key : $K\n";


#print "\ninput ASCII data to compute HMAC on -> ";
#$text = <STDIN>;
#$text = chomp($text);
$text = "what do ya want for nothing?";
print "Using data : $text\n";

# if key length > block size, reset key to sha1(key)
$Ksha1 = $Kmd5 = $K;
$Ksha1 = sha1($K) if length($K) > $B;
$Kmd5 = md5($K) if length($K) > $B;

# ipad = key xor '0x36' b times
my $k_ipadsha1 = $Ksha1 ^ (chr(0x36) x $B);
my $k_ipadmd5 = $Kmd5 ^ (chr(0x36) x $B);

# opad = key xor '0x5c' b times
my $k_opadsha1 = $Ksha1 ^ (chr(0x5c) x $B);
my $k_opadmd5 = $Kmd5 ^ (chr(0x5c) x $B);


# HMAC = sha1((key xor '0x5c'*B) || sha1((key xor '0x36'*B) || text))
# with || is concatenation

$Hsha1 = sha1($k_ipadsha1.$text);
$Hmd5 = md5($k_ipadmd5.$text);

$Hsha1 = sha1($k_opadsha1.$Hsha1);
$Hmd5 = md5($k_opadmd5.$Hmd5);

print "\n\nHMAC MD5==>\t".unpack("H*", $Hmd5)."\n";
print "HMAC SHA1==>\t".unpack("H*", $Hsha1)."\n";

