Reputation: 1880
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
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
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