我正在尝试使用PHP连接到API,并且需要正确的签名。
他们的文档一字不漏:
需要使用HMAC SHA-1哈希算法对命令字符串进行哈希处理 针对API密钥。结果字节数组应为Base64 以UTF-8格式编码,以便可以通过http传递。
要生成签名,您必须小写以下内容的完整列表: 请求参数并通过字段按字母顺序对每个参数进行排序 字段值对。生成的字符串要从上一个签名 带有密钥VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX的示例 是:
apikey = mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command = deployvirtualmachine&serviceofferingid = 21624abb-764e-4def-81d7-9fc54b5957fb&templateid = 54c83a5e-c548-4d91-8b14-5cf2d4 产生的签名值为:
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
问题:结果与他们的文档不符。知道我做错了什么吗?
答案 0 :(得分:5)
您的签名应这样生成:
$signature = urlencode(base64_encode(hash_hmac('sha1', $string , $key, true)));
最后一个参数的默认值为false
。然后,它将返回一个十六进制编码的字符串,而不是原始字节。然后,您必须按照文档中的说明对字节进行base64_encode。然后您必须对它进行urlencode,因为=
必须进行转换
答案 1 :(得分:0)
您应在$raw_output = TRUE
中设置hash_hmac()
。
另外,您应该使用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';
}