无法使用PHP HMAC SHA1和Base64创建身份验证字符串

时间:2019-01-10 00:00:04

标签: php laravel hash base64 sha1

所以我正在使用此API并使用Laravel,并且正在尝试构建auth字符串。这是我收到的文档,但是我遇到了一些麻烦,因为这对我来说是相对较新的东西。

这是身份验证说明:

  

authentication参数是一个字符串,它可以由   呼叫者或呼叫者可以选择将此值另存为参数   以及连接ID和API密钥。

     

身份验证是HMAC SHA1哈希的base64字符串。这是   使用in中的API密钥二进制文件进行计算

     ##########################格式为小写,以UTF8编码为键,计算机HMAC SHA1散列在      

################################格式中所有下面的连接ID   大小写和UTF8编码。

     

然后将结果二进制哈希值进行base64编码,并将文本结果为   应该作为身份验证参数传递的内容。在C#中的代码   计算身份验证可能类似于:

HMACSHA1 hmac = new HMACSHA1(
  UTF8Encoding.UTF8.GetBytes(apiKey.ToString("N").ToLower())
);
string authentication = Convert.ToBase64String(
  hmac.ComputeHash(
    UTF8Encoding.UTF8.GetBytes(connectionId.ToString("N").ToLower())
  )
);
     

例如以下凭据:

     

连接ID:5fecbc200f0e4a7cbf41040e11047e56

     

API密钥:2de51c4fd0f04b9fabeb95225e87da70

     

应导致计算出的认证值为   m5/Vc1RzhUETQvEtx/JdIglQpTg=

所以我一直在尝试:

$a = strtolower('5fecbc200f0e4a7cbf41040e11047e56');
$b = strtolower('2de51c4fd0f04b9fabeb95225e87da70');
$z = hash_hmac("sha1", utf8_encode(decbin($b)), utf8_encode(decbin($a)), true);
dd(base64_encode($z));

哪个输出QjG3kzUs7U1UukNd++3t24pBWNk=

我尝试了更多的变种,但我只是迷失了这个。第一次真正解码或编码任何东西。非常感谢任何可以帮助我解决此问题的技巧,想法或摘要。已经花了几个小时,这困扰着我。

1 个答案:

答案 0 :(得分:0)

首先:摆脱utf8_encode(),只是一般不使用它。假定输入字符串为ISO-88591-1,并且如果为其他任何内容,它将静默破坏数据。此功能的名称令人难以置信,因此,我什至建议任何人都不要使用它或相应的const meals = { food_meals: [ {meal_id: 15749, address_required: false, button_text: "choose", can_choose_meal: true}, {meal_id: 15750, address_required: false, button_text: "choose", can_choose_meal: true} ], wine_meals: [ {meal_id: 11651, address_required: false, button_text: "choose", can_choose_meal: true}, {meal_id: 4424, address_required: false, button_text: "choose", can_choose_meal: true} ], kids_meals: [ {meal_id: 15763, address_required: false, button_text: "choose", can_choose_meal: true}, {meal_id: 15764, address_required: false, button_text: "choose", can_choose_meal: true}, {meal_id: 15765, address_required: false, button_text: "choose", can_choose_meal: true} ] }; const idToFind = 15764; const foundEntry = Object.entries(meals) .find( ([, arr]) => arr.some( ({ meal_id }) => meal_id === idToFind ) ); if (foundEntry) { console.log(foundEntry[0]); },它会以相同的方式破坏您的数据,但相反。

如果您需要在PHP中转换字符串编码,请使用明确定义输入输出编码的内容,例如:mb_convert_encoding()。 [您仍然不需要它]

第二:无论您认为decbin()做什么,都是错误的。它将整数转换成由utf8_decode()0 字符组成的文字大写S字符串。

第三步::PHP字符串没有固有的编码,如果您扭动手臂进行描述,它们大致等效于字节数组。放入其中的字节就是从中取出的字节。

第四名:我不是C#专家[或中级,甚至是初学者],但是示例代码太可怕了。 1中的N的意义是什么?我找不到与此有关的任何文档。

从简单开始,使用有意义的变量名,构建并阅读文档

connectionId.ToString("N")

输出:

$connectionID = strtolower('5fecbc200f0e4a7cbf41040e11047e56');
$apiKey       = strtolower('2de51c4fd0f04b9fabeb95225e87da70');
$hash         = hash_hmac("sha1", $connectionID, $apiKey, true);
var_dump(base64_encode($hash));