【问题标题】:Hashes not similar between PHP and Paw REST ClientPHP 和 Paw REST 客户端之间的哈希值不相似
【发布时间】:2015-04-30 19:28:13
【问题描述】:

我正在构建 HMAC API,但在使用 Paw 测试散列时遇到问题。

在 Paw 我有这个有效载荷:

GET:/hello/world:"":9a6e30f2016370b6f2dcfb6880501d7f2305d69bout

和一个自定义的 HMAC-SHA256 变量(实际上是函数 like this 将其设置在 X-Hash 标头中。

X-Hash: 4Cq2yehWumDcUk1dYyfhm6qWjJVBkOCB8o12f5l0WGE=

在我的 PHP API 中,我有同样的东西:

GET:/hello/world:"":9a6e30f2016370b6f2dcfb6880501d7f2305d69bout

并使用:

hash_hmac('sha256', $this->getPayload(), '9a6e30f2016370b6f2dcfb6880501d7f2305d69bout', false);

所以在比较哈希时:

Paw: 4Cq2yehWumDcUk1dYyfhm6qWjJVBkOCB8o12f5l0WGE=
PHP: 6961b9d1f6e986c49d963cbebd691fa68dfa59b4ce3b7f05320c2d43eae3c7c3

它们非常不同。知道这是为什么吗?

更新

爪子代码:

function evaluate(context){
  var loc = getLocation(context.getCurrentRequest().url);

  var payload = "";
  payload += context.getCurrentRequest().method + ':';
  payload += loc.pathname + ':';
  payload += JSON.stringify(context.getCurrentRequest().body) + ':';
    payload += "9a6e30f2016370b6f2dcfb6880501d7f2305d69bout"; // Private key
  return payload;
};

function getLocation(href) {
    var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)(\/[^?#]*)(\?[^#]*|)(#.*|)$/);
    return match && {
        protocol: match[1],
        host: match[2],
        hostname: match[3],
        port: match[4],
        pathname: match[5],
        search: match[6],
        hash: match[7]
    }
}

PHP 代码(有很多 cmets):

if (strpos(strtoupper($authHeader), 'HMAC') !== 0) {
    echo 'out';
    throw new HttpForbiddenException();
}
else {
    $hmacSignature = $app->request->headers()->get('X-Hash');
    $publicKey = $app->request->headers()->get('X-Public');

    if ( empty($hmacSignature) || empty($publicKey) ) {
        echo 'out2';
        throw new HttpForbiddenException();
    }
    else {

        $this->hmacManager->setPublicKey($publicKey);
        print '$publickey = ' . $publicKey . '<br>';

        // Validate if base64_encoded or not
        if( base64_decode($hmacSignature, true) !== FALSE ) {
            $binaryString = base64_decode($hmacSignature);
            $hmacSignature = bin2hex($binaryString);
            print 'decoding ' . '<br>';
        }
        $this->hmacManager->setHmacSignature($hmacSignature);
        print '$hmacSignature = ' . $hmacSignature . '<br>';

        $this->hmacManager->setRequestMethod($app->request->getMethod());
        print 'method = ' . $app->request->getMethod() . '<br>';
        $this->hmacManager->setRequestResourceUri($app->request->getResourceUri());
        print 'uri = ' . $app->request->getResourceUri() . '<br>';

        $requestBody = $app->request()->getBody();
        if (Utils::isJson($requestBody)) {
            $requestBody = json_decode($requestBody);
        }
        $this->hmacManager->setRequestBody(json_encode($requestBody));
        print 'body = ' . json_encode($requestBody) . '<br>';

        print 'private key = ' . $this->hmacManager->getPrivateKey() . '<br>';

        $payload = '';
        $payload .= $this->hmacManager->getRequestMethod() . ":";
        $payload .= $this->hmacManager->getRequestResourceUri() . ":";
        $payload .= $this->hmacManager->getRequestBody() . ":";
        $payload .= $this->hmacManager->getPrivateKey();
        print 'PHP payload [' . $payload . ']';
        $this->hmacManager->setPayload($payload);

        $hmacValue = $this->hmacManager->generateHmac();
        $isValid = $this->hmacManager->isValid($this->hmacManager->generateHmac(), $hmacSignature);

        if ($isValid !== true) {
            echo 'out3';
            throw new HttpForbiddenException();
        }
    }
}

从另一个类生成Hmac:

public function generateHmac()
{
    print 'Generating HMAC' . '<br>';
    $algorithm = $this->getAlgorithm();
    print 'algo ' . $algorithm . '<br>';
    $privateKey = $this->getPrivateKey();
    print 'privk ' . $privateKey . '<br>';

    if (empty($algorithm)) {
        throw new \RuntimeException('Algorithm must be set and not empty');
    } elseif (empty($privateKey)) {
        throw new \RuntimeException('Private key must be set and not empty');
    }

    print 'payload ' . $this->getPayload() . '<br>';
    $hash = hash_hmac($this->getAlgorithm(), $this->getPayload(), $this->getPrivateKey(), false);
    print 'php hasj: ' . $hash . '<br>';

    return $hash;
}

最后,输出语句如下:

$publickey = 95f97b93560f951b4cae46c86d03d9b1a81d4ae8
decoding 
$hmacSignature = e02ab6c9e856ba60dc524d5d6327e19baa968c954190e081f28d767f99745861

method = GET
uri = /hello/world
body = ""
private key = 9a6e30f2016370b6f2dcfb6880501d7f2305d69bout
PHP payload [GET:/hello/world:"":9a6e30f2016370b6f2dcfb6880501d7f2305d69bout]

Generating HMAC
algo sha256
privk 9a6e30f2016370b6f2dcfb6880501d7f2305d69bout
payload GET:/hello/world:"":9a6e30f2016370b6f2dcfb6880501d7f2305d69bout
php hash: 6961b9d1f6e986c49d963cbebd691fa68dfa59b4ce3b7f05320c2d43eae3c7c3

希望对你有帮助!

【问题讨论】:

    标签: php hmac sha256 paw-app


    【解决方案1】:

    paw hash 是 base64 编码的,而 PHP 是十六进制的。所以先解码爪子哈希:

    $binary = base64_decode($pawHash);
    $hex = bin2hex($binary);
    

    然后将其与您自己的哈希值进行比较。

    【讨论】:

    • 我不能反其道而行之吗?在发送之前在 Paw 中解码生成的哈希,以便我的 API 保持原样?或者检测它是否是 base64 编码的?
    • 还是不行。我确实像你说的那样(并检查 base64_decode (str, true) !== FALSE)以确保它是一个 base64 字符串,但它现在给了我这个哈希:e02ab6c9e856ba60dc524d5d6327e19baa9​​68c954190e081f28d767f99745861 仍然与我在 PHP 中的不同。
    • 如果不查看其余代码,很难判断可能是什么问题。例如,有效载荷可能有问题。即使是微小的差异,哈希值也会看起来完全不同。
    • 让我哑口无言,我忘了给 Paw 在“密钥”字段中的私钥...AAAARG! @this.lau_ 你仍然对我帮助很大,所以我会接受你的回答!再次感谢!
    【解决方案2】:

    我们刚刚添加了新的Base 64 to Hex conversion dynamic values,这应该可以解决您的问题。

    将您的 HMAC 签名动态值包装在新的 Base 64 到 Hex one 中,您将获得一个有效的十六进制签名:

    您可以在此处安装这个新的动态值:Base 64 to Hex Dynamic Value

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 2017-07-22
      • 2019-04-21
      • 2012-01-21
      • 2010-09-25
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 2011-08-08
      相关资源
      最近更新 更多