错误:DescribeRegions API调用上的InvalidAction(Amazon AWS / EC2 API)

我正在编写一个与Amazon EC2 API进行交互的应用程序,因为我之前从未这样做过,所以我决定从像DescribeRegions这样容易的事情开始。

我在C中这样做,因此没有易于使用的库,所以我不得不与libcurl和libcrypto一起破解它。 完全披露,这是我第一次以编程方式与AWS / EC2 API交互,所以这可能是一个愚蠢的新手错误。

我确实读过了stackoverflow; 这与该人试图从bash发送请求并且未引用该字符串的问题不同。 我通过curl_easy_perform()发送请求

在阅读了我能找到的所有文档之后(对于这个示例,让我为我的AWS Access密钥替换AAAAAAAAA,为我的密钥替换BBBBBBB。

我构建了签名请求的参数部分,如下所述:

 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 

当我发送它时,我收到以下错误。

  SignatureDoesNotMatchThe 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.585f8932-d27b-42b3-b20e-453d8c7ee1ef 

我正在使用的签名机制是一个简单的hmac_sha256; 我还尝试了维基百科文章中引用的hmac_sha256库,可在此处下载 。

我已经validation我的签名算法是正确的,现在我只能假设我签名的字符串不正确。

遗憾的是,文档(AWS文档)在这方面不够充分。

例如,它显示为 :

添加查询字符串组件(名称 – 值对,不包括初始问号(?)作为UTF-8字符,这些字符按RFC 3986进行URL编码(hex字符必须为大写字母)并使用字典字节顺序排序。字典字节顺序区分大小写。

究竟他们要我在这里排序?

非常感激任何的帮助。 如果我在这里发布完整的源代码会有帮助吗?

究竟他们要我在这里排序?

一组键/值对中的键没有定义的排序顺序,但由于只能有一个正确的签名算法输出,因此根据定义,只能有一个正确的输入…而正确的输入是一个字符串,通过附加键/值对来构造,其中键被排序。

在构建要签名的字符串时,您可以对查询字符串中的键(名称)进行排序。 例如,“AWSAccessKeyId”在“SignatureMethod”之前,它位于“Timestamp”之前。等等。您可以使用已排序的键构建字符串。

但我认为你遇到的另一个问题是:

继续逃避并生成签名请求

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

等待。 在构建此字符串时,您只能urlencode(转义)键和值,而不是分隔符。 看起来应该更像这样:

 Action=DescribeRegions&AWSAccessKeyId= ... 

请注意,在示例中,您看到的唯一转义类似于时间戳中的转义,其中:变为%3A但查询字符串中的= an &不会转义。 在构建字符串之前,您需要转义键和值,而不是之后。

感谢Michael和我现在看不到的另一个答案,这些谜团已经解决了。

完整的解决方案就是……

  1. 正如迈克尔所说,各种键/值对必须按字母顺序排序,而AWSAccessKeyId在Action之前(我正在犯错)。
  2. 我在签名请求的构造中编码=和&的URI。
  3. HMAC_Final根据请求构造您的签名,但不会给您一个空终止字符串; 您应该意识到SHA256的长度为32个字节,并将空终结符放在正确的位置。

正确答案归功于迈克尔!

Interesting Posts