PHP: 如何生成字符串的 hmac SHA1 签名?

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

我正在尝试使用 PHP 连接到 API 并且需要正确的签名。

他们的文档逐字记录:

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

示例尝试:

$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';
}

结果: 9077d90baa7ab8913811b64a50814b640dce60eb

假设为:ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D

问题:结果与他们的文档不符。知道我做错了什么吗?

您的签名应该像这样生成:

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

最后一个参数的默认值为false。然后它将 return 一个十六进制编码的字符串而不是原始字节。然后你必须 base64_encode 文档中所述的字节。然后你必须对其进行 urlencode,因为 = 必须被转换

您应该在 hash_hmac() 中设置 $raw_output = TRUE。 你也应该使用 strcmp() 而不是 ==

因此实际代码将是



$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';
}