Kyle Anderson
Kyle Anderson

Reputation: 1880

PHP: How can I generate a hmac SHA1 signature of a string?

I am trying to connect to an API using PHP and need the correct signature.

Their documentation verbatim:

The command string needs to hashed using HMAC SHA-1 hashing algorithm against the API secret key. The resulting byte array should be Base64 encoded in UTF-8 format so that it can be passed via http.

To generate the signature you have to lower case the complete list of request parameters and sort them alphabetically via the field for each field-value pair. The resulting string to sign from the previous example with a secret key VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX would be:

apikey=mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11

Resulting in a signature value of:

ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D

Example Attempt:

$string = 'apikey=mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11
';
$string = utf8_encode(strtolower($string));
$key = 'VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX';
$signature = hash_hmac('sha1', $string , $key);
print 'SIGNATURE:'.$signature.'<br>';
if($signature=='ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D'){
    print 'SUCCESS';
}else{
    print 'FAIL';
}

RESULT: 9077d90baa7ab8913811b64a50814b640dce60eb

Suppose To Be: ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D

QUESTION: Result does NOT match their documentation. Any idea what I did wrong?

Upvotes: 4

Views: 5842

Answers (2)

Ajanyan Pradeep
Ajanyan Pradeep

Reputation: 1132

You should set $raw_output = TRUE in hash_hmac(). Also you should use strcmp() instead of ==

So the actual code will be



$string = 'apikey=mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11
';
$string = utf8_encode(strtolower($string));
$key = 'VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX';
$signature = urlencode(base64_encode(hash_hmac('sha1', $string , $key, $raw_output=TRUE))); 
print 'SIGNATURE:'.$signature.'<br>';
if(strcmp($signature,'ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D'))
{
    print 'SUCCESS';
}
else
{
    print 'FAIL';
}

Upvotes: 0

Sindhara
Sindhara

Reputation: 1473

Your signature should be generated like this:

$signature = urlencode(base64_encode(hash_hmac('sha1', $string , $key, true)));

The last parameter's default value is false. Then it'll return a hex-coded string instead of raw bytes. Then you have to base64_encode the bytes as stated in the documentation. And then you'll have to urlencode it as the = has to be transformed

Upvotes: 6

Related Questions