2013-09-22 6 views
1

Я пишу приложение для взаимодействия с API Amazon EC2, и, поскольку я никогда раньше этого не делал, я решил начать с чего-то простого, как DescribeRegions.Ошибка: InvalidAction на вызов API DescribeRegions (API Amazon AWS/EC2)

Я делаю это в C, поэтому для этого нет простых в использовании библиотек, поэтому мне нужно взломать его вместе с libcurl и libcrypto. Полное раскрытие информации, это первый раз, когда я взаимодействую с API AWS/EC2 программно, так что это может быть глупой ошибкой новичка.

Я прочитал через stackoverflow; это не то же самое, что и question, где человек пытался отправить запрос из bash и не процитировал строку. Я посылаю запрос через curl_easy_perform()

После прочтения всей документации, которую я мог найти (и для этого примера, позвольте мне заменить AAAAAAAAA для моего AWS Access Key и 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; Я также попробовал библиотеку hmac_sha256, указанную в wikipedia article и доступную для 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», который идет до «Timestamp» и т. Д. Вы создаете строку с отсортированными ключами.

Но я думаю, что другой вопрос, у вас есть это:

proceed to escape that and generate a signing request of

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

Подождите. При создании этой строки вы только urlencode (escape) ключи и значения, а не разделители. Это должно выглядеть следующим образом:

Action=DescribeRegions&AWSAccessKeyId= ... 

Обратите внимание на примерах, только спасаясь вы видите, как те, что в метку времени, где : становится %3A, но в =& в строке запроса не спасся. Перед созданием строки вам нужно будет избежать ключей и значений, а не после.

0

Благодаря Michael и еще одному ответу, который я не вижу прямо сейчас, тайны решены.

Полное разрешение это ...

  1. как говорит Майкл, различные пары ключ/значение, должны быть отсортированы в алфавитном порядке и AWSAccessKeyId предваряет Действие (что то, что я делал ошибку на) ,
  2. Я был кодировкой URI = и & при построении запроса подписи.
  3. HMAC_Final создает вашу подпись в соответствии с запросом, но не дает вам нулевую нулевую строку ; вам нужно понять, что SHA256 составляет 32 байтов и положить нулевой ограничитель в нужное место.

Правильный ответ кредит принадлежит Майклу!