2010-10-16 61 views
1

我需要签署我的亚马逊产品API请求,接受的代码如下。PHP hash_hmac()操作系统区别

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

,当我在64位Linux,但,当我在64位Windows 7有没有人有任何想法如何调试为什么hash_hmac提供64位版和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)); 

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

非base64编码值是5f451372df57489ff793682eea7a322a14e592cc7965b1f8a806c2c96df35f8f为不正确的和35a71ef94dc0cf83a137bb484aa82cd6f74b0470448a359c05e0aa2f9c4df718对于正确的转换为十六进制。 (这是在调用原始的二进制输出)

编辑2我的猜测现在的问题是,即使Windows 7操作系统是64位的PHP二进制文件编译为32位,因为我无法找到关于PHP的64位版本。网站。

编辑3我其实很确定现在问题是二进制是32位。很可能,Linux上的PHP使用操作系统版本来计算哈希值,而Windows上的PHP实现它自己的版本,即使两个操作系统都是64位,也会导致32/64位的差异。

+0

它可能有助于给我们不正确的输出以及... – 2010-10-16 16:20:27

+0

我做了大约10分钟之前,你评论说?... – 2010-10-16 16:29:28

+0

@Martin:我也只看到正确的输出。你能包含来自Linux和Windows系统的输出吗? – 2010-10-16 16:46:54

回答

3

恭喜,欢迎来到行结尾的奇妙世界。你遇到的问题是一个经典问题:* 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"; 
+0

你忍住了我自己的回应,所以有代表。 :) – 2010-11-24 01:27:41

+0

不幸的是,它仍然不适合我。我认为这是我自己的困惑。在我的Linux机器上,它工作正常,但只有当我在一个单独的行上键入所有内容。当我用手动插入换行符的方式将它放在一行上时,我得到与窗口一样的相同内容...这不是正确的输出。更糟糕的是,我试图用一些可见的字符替换\ n或\ r并打印它,但它看起来好像都不在我的字符串中。也许我应该开一个新的问题? – Jere 2010-11-24 03:04:30

+0

我正在使用单引号。卫生署!不知道换行符不会被单引号解释。 – Jere 2010-11-24 03:09:58

0

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

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

相当于

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

所以,如果有这两者之间没有什么区别,我猜测的错误在于SHA256的实施。无论哪种方式,这是一个错误。在php.net上报告,并需要一个新的构建。

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

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)); 
0

请注意,相对于亚马逊卖家的Web服务,在您的文章的字符串也很重要,似乎他们有他们内部维护所有的post数据排序顺序,这是参数,多数民众赞成的顺序用于准备用于生成签名的字符串。如果你使用画板,你可以得到参数的顺序,我没有注意到任何文档。

+1

这个答案似乎与问题没有任何关系,OP明确指出问题出在OS平台上,而不是与正在发送的参数有关。 – 2012-09-24 07:35:17