2010-10-16 126 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