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

PHP:如何生成字符串的hmac SHA1签名?,php,hmac,hmacsha1,Php,Hmac,Hmacsha1,我正在尝试使用PHP连接到API,需要正确的签名 他们的文档逐字记录: $string = 'apikey=mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=

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

他们的文档逐字记录:

$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';
}
命令字符串需要使用HMAC SHA-1散列算法进行散列 针对API密钥。结果字节数组应为Base64 以UTF-8格式编码,以便可以通过http传递

要生成签名,您必须将完整的签名列表小写 请求参数,并通过字段按字母顺序对每个参数进行排序 字段值对。要从上一个字符串签名的结果字符串 使用密钥vdaacyb0lv9enjteioelcvqkvjck_J_QljX的示例 是:

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

导致签名值为:

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';
}
$string='apikey=mivr6x7u6bnsdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11
';
$string=utf8_编码(strtolower($string));
$key='vdaacyb0lv9enjteioelcvqkvjck_J_QljX';
$signature=hash_hmac('sha1',$string,$key);
打印“签名:”.$SIGNATURE.“
”; 如果($signature=='ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D'){ 打印“成功”; }否则{ 打印“失败”; }
结果:9077D90BAA7AB891381B64A50814B640DCE60EB

假设为:ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D


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

您的签名应该如下生成:

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

最后一个参数的默认值是
false
。然后它将返回一个十六进制编码的字符串,而不是原始字节。然后您必须按照文档中的说明对字节进行base64_编码。然后您必须对其进行URL编码,因为必须转换
=

您应该在
hash\u hmac()中设置
$raw\u 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';
}


$string='apikey=mivr6x7u6bnsdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11
';
$string=utf8_编码(strtolower($string));
$key='vdaacyb0lv9enjteioelcvqkvjck_J_QljX';
$signature=urlencode(base64_编码(hash_hmac('sha1',$string,$key,$raw_output=TRUE));
打印“签名:”.$SIGNATURE.“
”; if(strcmp($signature,'ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D')) { 打印“成功”; } 其他的 { 打印“失败”; }
这肯定更近了。返回的签名与文档示例的长度相同,但不匹配。现在,我得到了kHfZC6p6uJE4EbZKUIFLZA3OYOs%3D,而不是预期的ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D删除字符串中的换行符