【问题标题】:PHP: How can I generate a hmac SHA1 signature of a string?PHP:如何生成字符串的 hmac SHA1 签名?
【发布时间】:2019-03-19 18:15:17
【问题描述】:

我正在尝试使用 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-5cf2d4c081ee&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';
}

结果: 9077d90baa7ab8913811b64a50814b640dce60eb

假设为:ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D

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

【问题讨论】:

    标签: php hmac hmacsha1


    【解决方案1】:

    你的签名应该是这样生成的:

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

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

    【讨论】:

    • 这肯定更接近。返回的签名与文档示例的长度相同,但不匹配。现在我得到 kHfZC6p6uJE4EbZKUIFLZA3OYOs%3D 而不是预期的 ahlpA6J1Fq6OYI1HFrMSGgBt0WY%3D
    • 删除字符串中的换行符
    【解决方案2】:

    您应该在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';
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2019-11-01
      • 2011-05-04
      • 2019-10-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多