简体   繁体   English

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

[英]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. 我正在尝试使用PHP连接到API并需要正确的签名。

Their documentation verbatim: 他们的文件逐字记录:

The command string needs to hashed using HMAC SHA-1 hashing algorithm against the API secret key. 命令字符串需要使用针对API密钥的HMAC SHA-1散列算法进行散列。 The resulting byte array should be Base64 encoded in UTF-8 format so that it can be passed via http. 生成的字节数组应该是UTF-8格式的Base64编码,以便可以通过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: 使用密钥VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX从前一个示例签名的结果字符串将是:

apikey=mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&command=deployvirtualmachine&serviceofferingid=21624abb-764e-4def-81d7-9fc54b5957fb&templateid=54c83a5e-c548-4d91-8b14-5cf2d4c081ee&zoneid=1128bd56-b4d9-4ac6-a7b9-c715b187ce11 apikey = mivr6x7u6bn_sdahobpjnejpgest35exqjb8cg20&命令= 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 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 结果: 9077d90baa7ab8913811b64a50814b640dce60eb

Suppose To Be: ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D 假设是:ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D

QUESTION: Result does NOT match their documentation. 问题:结果与他们的文档不符。 Any idea what I did wrong? 知道我做错了什么吗?

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 . 最后一个参数的默认值为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. 然后你必须按照文档中的说明对字节进行base64_encode。 And then you'll have to urlencode it as the = has to be transformed 然后你必须对它进行urlencode,因为=必须进行转换

You should set $raw_output = TRUE in hash_hmac() . 你应该在hash_hmac()设置$raw_output = TRUE Also you should use strcmp() instead of == 你也应该使用strcmp()而不是==

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM