各位开发者好,
我遇到了加载回调(以及扩展卸载回调)的问题。
我正在尝试按照文档中描述的算法验证请求的真实性。 https://developer.bigcommerce.com/apps/load#signed-payload
我能够解码 json 字符串并且数据正确,但签名永远不匹配。我确保使用正确的客户端 key ,并尝试了不同的编码/解码方案,但没有成功。
另一个问题是他们在示例中(以及在他们的 sample app 中)提供的代码片段(PHP)。当签名匹配时,它们似乎返回 null,而当它们不匹配时,它们似乎返回了解码数据……( try secureCompare() )
这意味着每次都会通过安全测试,因为在我所有的尝试中,签名都不匹配。
我在这里错过了什么吗?
编辑:这是文档中的示例。我真的不能给你样本数据,因为客户的 secret 是保密的......
function verify($signedRequest, $clientSecret)
{
list($payload, $encodedSignature) = explode('.', $signedRequest, 2);
// decode the data
$signature = base64_decode($encodedSignature);
$data = json_decode(base64_decode($payload), true);
// confirm the signature
$expectedSignature = hash_hmac('sha256', $payload, $clientSecret, $raw = true);
if (secureCompare($signature, $expectedSignature)) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function secureCompare($str1, $str2)
{
$res = $str1 ^ $str2;
$ret = strlen($str1) ^ strlen($str2); //not the same length, then fail ($ret != 0)
for($i = strlen($res) - 1; $i >= 0; $i--) {
$ret += ord($res[$i]);
}
return !$ret;
}
最佳答案
您没有遗漏任何东西,也不是时钟同步问题 - here 和 here 提供的 28 行示例代码有一些非常严重的缺陷:
hash_hmac
,而不是 base64 解码的 JSON。 (BigCommerce API 提供给您的哈希实际上是 base64- 解码的 JSON 的哈希)。 hash_hmac
是用 $raw=true
调用的,这意味着两个字符串总是有很大的不同:一个是原始二进制,另一个是十六进制。 secureCompare
逻辑检查错误。 if (secureCompare...
函数的 verify
部分期望与 secureCompare
函数相反的行为。如果在字符串匹配时 secureCompare 函数返回 true,我们为什么要调用 error_log
? 把所有这三个问题放在一起,你最终得到的代码看起来可以工作,但实际上却默默地失败了。如果您使用示例代码,您可能会允许您的应用程序处理任何和所有“签名”请求!
这是我更正的
verify
函数实现:<?php
function verifySignedRequest($signedRequest, $clientSecret)
{
list($encodedData, $encodedSignature) = explode('.', $signedRequest, 2);
// decode the data
$signature = base64_decode($encodedSignature);
$jsonStr = base64_decode($encodedData);
$data = json_decode($jsonStr, true);
// confirm the signature
$expectedSignature = hash_hmac('sha256', $jsonStr, $clientSecret, $raw = false);
if (!hash_equals($expectedSignature, $signature)) {
error_log('Bad signed request from BigCommerce!');
return null;
}
return $data;
}