你好开发者,
我遇到了加载回调问题(以及扩展名的卸载回调).
我正在尝试按照文档中描述的算法验证请求的真实性. https://developer.bigcommerce.com/apps/load#signed-payload
我能够解码json字符串,数据是正确的,但签名永远不会匹配.我确保使用正确的客户端秘密并尝试了不同的编码/解码方案,没有运气.
另一个问题是它们在示例中(以及在其sample app中)提供的代码片段(PHP).它们似乎在签名匹配时返回null,而在它们不匹配时返回解码数据…(try secureCompare())
这意味着安全测试每次都会通过,因为在我的所有尝试中,签名都不匹配.
我在这里错过了什么吗?
编辑:这是doc中的示例.我不能真正给你样本数据,因为客户的秘密是保密…
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;
}
最佳答案 你没有遗漏任何东西,这不是时钟同步问题 – 提供的28行示例代码
here和
here都有一些非常严重的缺陷:
>示例代码执行原始base64编码的JSON的hash_hmac,而不是base64解码的JSON. (BigCommerce API为您提供的哈希实际上是base64解码的JSON的哈希值).
>由于使用$raw = true调用hash_hmac,这意味着两个字符串将始终存在巨大差异:一个是原始二进制,另一个是十六进制.
>检查secureCompare逻辑是否错误. if(secureCompare …部分验证函数需要与secureCompare函数相反的行为.如果secureCompare函数在字符串匹配时返回true,为什么我们调用error_log?
将所有这三个问题放在一起,最终得到的代码看起来有效,但实际上是默默无效的.如果您使用示例代码,您可能会允许您的应用程序处理任何和所有“签名”请求!
这是我更正的验证函数实现:
<?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;
}