2013-09-22 94 views
1

我正在編寫一個應用程序來與Amazon EC2 API進行交互,因爲我之前從未做過這個操作,所以我決定從像DescribeRegions這樣簡單的東西開始。錯誤:DescribeRegions API調用(Amazon AWS/EC2 API)上的InvalidAction

我在C中這樣做,所以沒有易於使用的庫,因此我不得不將它與libcurl和libcrypto一起破解。完全公開,這是我第一次以編程方式與AWS/EC2 API交互,所以這可能是一個愚蠢的新手錯誤。

我確實通過了stackoverflow;這與question不同,該人試圖從bash發送請求並且未引用該字符串。我通過curl_easy_perform()

發送請求閱讀完所有的文件我能找到後(並在這個例子中,讓我代替AAAAAAAAA我的AWS訪問密鑰和BBBBBBB我的祕密密鑰。

我構建參數如所描述的here簽名請求的一部分,其讀取:

Action=DescribeRegions&AWSAccessKeyId=AAAAAAAA&SignatureMethod=HmacSHA256&"SignatureVersion=2&Timestamp=2013-09-22T02:12:27Z&Version=2013-08-15 

並繼續逃脫和產生的

GET\n 
ec2.amazonaws.com\n 
/\n 
Action%3DDescribeRegions%26AWSAccessKeyId%AAAAAAAAAAAA%26SignatureMethod%3DHmacSHA256%26SignatureVersion%3D2%26Timestamp%3D2013-09-22T02%3A12%3A27Z&Version=2013-08-15 
一個簽名請求

,然後我可以開始創建一個簽名(我們稱之爲CCCCCCCC)

,並拿出讀取請求:

https://ec2.amazonaws.com/?Action%3DDescribeRegions%26AWSAccessKeyId%3DAAAAAAAAAAAAA%26SignatureMethod%3DHmacSHA256%26SignatureVersion%3D2%26Timestamp%3D2013-09-22T02%3A12%3A27Z&Version=2013-08-15&Signature=CCCCCCCCCCC 

當我一起發送,我得到了下面的錯誤。

<?xml version="1.0" encoding="UTF-8"?> 
<Response><Errors><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message></Error></Errors><RequestID>585f8932-d27b-42b3-b20e-453d8c7ee1ef</RequestID></Response> 

我使用的簽名機制是一個簡單的hmac_sha256;我也嘗試了wikipedia article中引用的hmac_sha256庫,並且可用於download here

我已驗證我的簽名算法是正確的,現在我只能假定我簽名的字符串不正確。

在這方面,文檔(AWS文檔)不幸是不夠的。

例如,reads

Add the query string components (the name-value pairs, not including the initial question mark (?) as UTF-8 characters which are URL encoded per RFC 3986 (hexadecimal characters must be uppercased) and sorted using lexicographic byte ordering. Lexicographic byte ordering is case sensitive.

究竟是他們問我怎麼在這裏進行排序?

任何幫助將不勝感激。如果我在這裏發佈完整的源代碼會有幫助嗎?

回答

2

What exactly are they asking me to sort here?

一組鍵的鍵/值對沒有定義的排序順序,但因爲只能有簽名算法的一個正確的輸出,也可以通過定義只有一個正確的輸入和...正確的輸入是通過將鍵/值對與鍵排序而構造的字符串。

在構建要簽名的字符串時,可以對查詢字符串中的鍵(名稱)進行排序。例如,「AWSAccessKeyId」在「時間戳」之前的「SignatureMethod」之前。您可以使用排序的鍵來構建字符串。

但我認爲你有其他的問題是這樣的:

proceed to escape that and generate a signing request of

... 
Action%3DDescribeRegions%26AWSAccessKeyId%AAAAAAAAAAAA ... 

等待。構建此字符串時,您只需對密鑰和值進行urlencode(轉義),而不是分隔符。它應該看起來更像是這樣的:在實例

Action=DescribeRegions&AWSAccessKeyId= ... 

通知,唯一的逃避你看到的是像在戳,其中:變得%3A找到,但在查詢字符串的=&都沒有逃過。您需要在構建字符串之前轉義鍵和值,而不是之後。

0

感謝Michael以及我現在看不到的另一個答案,這些謎題已解決。

完整的分辨率是這樣...

  1. 邁克爾說,不同的鍵/值對必須按照字母順序排序 和AWSAccessKeyId去之前行動(這是 東西,我是在做錯誤) 。
  2. 我是URI編碼=和&在簽署請求的構造。
  3. HMAC_Final根據請求構造您的簽名,但不會給您一個空 已終止的字符串;您應該認識到SHA256的長度爲32, 字節,並將空終止符放在正確的位置。

正確的答案功勞歸功於邁克爾!