首页 文章

PHP hash_hmac()操作系统的区别

提问于
浏览
1

我需要签署我的Amazon Product API请求,接受的代码执行此操作如下 .

base64_encode(hash_hmac('sha256', $request, $key, true));

当我在64位Linux上时这很好用但是当我在64位Windows 7时失败 . 有没有人有任何想法如何调试为什么hash_hmac在64位Linux和64位Windows之间提供不同的输出?

测试代码:

<?php
$test = "GET
webservices.amazon.com
/onca/xml
AWSAccessKeyId=00000000000000000000&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06";
#echo $test;
echo base64_encode(hash_hmac('sha256', $test, '1234567890', true));

Edit 上面代码的正确输出是 Nace+U3Az4OhN7tISqgs1vdLBHBEijWcBeCqL5xN9xg= 不正确的输出是 X0UTct9XSJ/3k2gu6noyKhTlksx5ZbH4qAbCyW3zX48=

非base64编码的值为 5f451372df57489ff793682eea7a322a14e592cc7965b1f8a806c2c96df35f8f 表示错误, 35a71ef94dc0cf83a137bb484aa82cd6f74b0470448a359c05e0aa2f9c4df718 表示正确的值,当转换为十六进制时 . (它是调用中的原始二进制输出)

Edit 2 我现在的猜测是,即使Windows 7操作系统是64位,PHP二进制文件编译为32位,因为我在php.net网站上找不到64位版本 .

Edit 3 I 'm actually pretty sure now that the problem is that the binary is 32bit. Most likely PHP on linux uses an OS version to calculate the hash while PHP on windows implements it'自己的版本,即使两个操作系统都是64位,也会导致32/64位差异 .

4 回答

  • 0

    自从我弄清问题以来,问题就一直悬而未决,而且大多数问题通常都是PEBCAC .

    答案不是32而不是64位,而是行结尾 . Linux有\ n而Windows有\ r \ n .

    将它全部写在一行并明确使用\ n,它应该可以工作 .

    $test = "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=00000000000000000000&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06";
    echo base64_encode(hash_hmac('sha256', $test, '1234567890', true));
    
  • 3

    请注意,对于亚马逊卖家网络服务,你的帖子字符串中的参数顺序也很重要,似乎他们有一个排序顺序,他们在内部维护所有post params,用于准备字符串是用于生成签名 . 如果您使用草图,您可以获得参数的顺序,我没有注意到任何文档 .

  • 0

    您可以使用 mhash() 验证输出 . 它遵循相同的算法 .

    hash_hmac("sha256", "data", "key");
    

    相当于

    bin2hex(mhash(MHASH_SHA256, "data", "key"));
    

    所以如果这两者之间没有区别,我猜测错误在于sha256的实现 . 无论哪种方式,这都是一个错误 . 在php.net上报告并要求新建 .

    您还可以在两个平台上使用 hash("sha256", "test"); 进行测试,以进一步调试哪一个正常工作 . "test"应该成为9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

  • 0

    恭喜,欢迎来到精彩的终结世界 . 你遇到的问题是经典问题:* nix中的行结尾是 \n ,而windows中的行结尾是 \r\n . 请尝试以下方法:

    $test = "GET\n".
    "webservices.amazon.com\n".
    "/onca/xml\n".
    "AWSAccessKeyId=00000000000000000000&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06";
    

相关问题