简体   繁体   English

使用c#的Amazon ec2 API版本2签名编码

[英]Amazon ec2 API version 2 signature encoding with c#

I am having a problem with encoding the hash for the Version 2 Signature of the ec2 API. 我在为ec2 API的第2版签名编码哈希时遇到问题。

Note my Version 1 Signature hashing works fine, but this is depreciated and I will need to move to version 2. So firstly here is the code that works... 注意我的版本1签名哈希工作正常,但这是折旧的,我将需要转移到版本2.所以首先这里是有效的代码...

parameters is just a dictionary, what I have to do is simply sort the parameters by key and append each value-pair with no delimeters, then hash that string against my key. 参数只是一个字典,我要做的只是按键对参数进行排序,并附加没有分隔符的每个值对,然后对我的密钥散列该字符串。 (again, note this works fine) (再说一遍,注意这很好用)

private string GetVersion1Sig()
{
  string sig = string.Join(string.Empty, parameters.OrderBy(vp => vp.Key).Select(p => string.Format("{0}{1}", p.Key, p.Value)).ToArray());
  UTF8Encoding encoding = new UTF8Encoding();
  HMACSHA256 signature = new HMACSHA256(encoding.GetBytes(_secretAccessKey));
  byte[] hash = signature.ComputeHash(encoding.GetBytes(sig));
  string result = Convert.ToBase64String(hash);
  return result;
}

Now, with Version 2 there are some changes, here is the doco from the API developers guide... 现在,对于版本2,有一些更改,这里是来自API开发人员指南的doco ...

  1. Create the canonicalized query string that you need later in this procedure: 创建以后在此过程中需要的规范化查询字符串:

a. 一个。 Sort the UTF-8 query string components by parameter name with natural byte ordering. 使用自然字节顺序按参数名称对UTF-8查询字符串组件进行排序。 The parameters can come from the GET URI or from the POST body (when Content-Type is application/x-www-form-urlencoded). 参数可以来自GET URI或POST主体(当Content-Type为application / x-www-form-urlencoded时)。

b. URL encode the parameter name and values according to the following rules: URL根据以下规则对参数名称和值进行编码:

• Do not URL encode any of the unreserved characters that RFC 3986 defines. •不要对RFC 3986定义的任何未保留字符进行URL编码。 These unreserved characters are AZ, az, 0-9, hyphen ( - ), underscore ( _ ), period ( . ), and tilde ( ~ ). 这些未保留的字符是AZ,az,0-9,连字符( - ),下划线(_),句点(。)和波浪号(〜)。
• Percent encode all other characters with %XY, where X and Y are hex characters 0-9 and uppercase AF. •百分比用%XY编码所有其他字符,其中X和Y是十六进制字符0-9和大写AF。
• Percent encode extended UTF-8 characters in the form %XY%ZA.... •百分比编码扩展的UTF-8字符,格式为%XY%ZA ....
• Percent encode the space character as %20 (and not +, as common encoding schemes do). •百分比将空格字符编码为%20(而不是像普通编码方案那样编码)。

Note 注意
Currently all AWS service parameter names use unreserved characters, so you don't need to encode them. 目前,所有AWS服务参数名称都使用未保留的字符,因此您无需对其进行编码。 However, you might want to include code to handle parameter names that use reserved characters, for possible future use. 但是,您可能希望包含代码以处理使用保留字符的参数名称,以备将来使用。

c. C。 Separate the encoded parameter names from their encoded values with the equals sign ( = ) (ASCII character 61), even if the parameter value is empty. 使用等号(=)(ASCII字符61)将编码参数名称与其编码值分开,即使参数值为空。

d. d。 Separate the name-value pairs with an ampersand ( & ) (ASCII code 38). 使用与号(&)(ASCII代码38)分隔名称 - 值对。

  1. Create the string to sign according to the following pseudo-grammar (the "\\n" represents an ASCII newline). 根据以下伪语法创建要签名的字符串(“\\ n”表示ASCII换行符)。 StringToSign = HTTPVerb + "\\n" + ValueOfHostHeaderInLowercase + "\\n" + HTTPRequestURI + "\\n" + StringToSign = HTTPVerb +“\\ n”+ ValueOfHostHeaderInLowercase +“\\ n”+ HTTPRequestURI +“\\ n”+
    CanonicalizedQueryString The HTTPRequestURI component is the HTTP absolute path component of the URI up to, but not including, the query string. CanonicalizedQueryString HTTPRequestURI组件是URI的HTTP绝对路径组件,但不包括查询字符串。 If the HTTPRequestURI is empty, use a forward slash ( / ). 如果HTTPRequestURI为空,请使用正斜杠(/)。
  2. Calculate an RFC 2104-compliant HMAC with the string you just created, your Secret Access Key as the key, and SHA256 or SHA1 as the hash algorithm. 使用刚刚创建的字符串,密钥访问密钥作为密钥,使用SHA256或SHA1作为哈希算法,计算符合RFC 2104的HMAC。 For more information, go to http://www.rfc.net/rfc2104.html . 有关更多信息,请访问http://www.rfc.net/rfc2104.html
  3. Convert the resulting value to base64. 将结果值转换为base64。
  4. Use the resulting value as the value of the Signature request parameter. 使用结果值作为Signature请求参数的值。

So what I have is.... 所以我拥有的是......

private string GetSignature()
{
  StringBuilder sb = new StringBuilder();
  sb.Append("GET\n");
  sb.Append("ec2.amazonaws.com\n");
  sb.Append("/\n");
  sb.Append(string.Join("&", parameters.OrderBy(vp => vp.Key, new CanonicalizedDictCompare()).Select(p => string.Format("{0}={1}", HttpUtility.UrlEncode(p.Key), HttpUtility.UrlEncode(p.Value))).ToArray()));
  UTF8Encoding encoding = new UTF8Encoding();
  HMACSHA256 signature = new HMACSHA256(encoding.GetBytes(_secretAccessKey));
  byte[] hash = signature.ComputeHash(encoding.GetBytes(sb.ToString()));
  string result = Convert.ToBase64String(hash);
  return result;
}

for completeness here is the IComparer implementation.... 为了完整性,这里是IComparer实现....

  internal class CanonicalizedDictCompare : IComparer<string>
  {
    #region IComparer<string> Members

    public int Compare(string x, string y)
    {
      return string.CompareOrdinal(x, y);
    }

    #endregion
  }

As far as I can tell I have done everything I need to do for this hash, but I keep getting an error from the server telling me that my signature is incorrect. 据我所知,我已经完成了我需要为此哈希做的所有事情,但我不断从服务器收到错误,告诉我我的签名不正确。 Help... 救命...

Ok, I figured it out....The UrlEncoding in the HttpUtility class does not conform to the Amazon encoding scheme....grrr (specifically the hex value after the % in the .NET utility is lowercase, not uppercase) 好吧,我想通了...... HttpUtility类中的UrlEncoding不符合亚马逊编码方案.... grrr(特别是.NET实用程序中的%之后的十六进制值是小写,而不是大写)

b. URL encode the parameter name and values according to the following rules: URL根据以下规则对参数名称和值进行编码:

  • Do not URL encode any of the unreserved characters that RFC 3986 defines. 不要对RFC 3986定义的任何未保留字符进行URL编码。 These unreserved characters are AZ, az, 0-9, hyphen ( - ), underscore ( _ ), period ( . ), and tilde ( ~ ). 这些未保留的字符是AZ,az,0-9,连字符( - ),下划线(_),句点(。)和波浪号(〜)。
  • Percent encode all other characters with %XY, where X and Y are hex characters 0-9 and uppercase AF . 百分比使用%XY编码所有其他字符,其中X和Y是十六进制字符0-9和大写AF

  • Percent encode extended UTF-8 characters in the form %XY%ZA.... 百分比编码扩展的UTF-8字符,格式为%XY%ZA ....

  • Percent encode the space character as %20 (and not +, as common encoding schemes do). 百分比将空格字符编码为%20(而不是+,如常见的编码方案那样)。

So after writing a quick method that encodes to this scheme, it works fine. 因此,在编写了一个编码到这个方案的快速方法之后,它运行正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM