代码之家  ›  专栏  ›  技术社区  ›  Tim Jarvis

AmazonEC2API版本2签名编码与c#

  •  6
  • Tim Jarvis  · 技术社区  · 16 年前

    注意,我的第1版签名散列可以正常工作,但这已经被贬低了,我需要转到第2版。因此,首先,这里是工作的代码。。。

    参数只是一个字典,我所要做的只是按键对参数排序,并附加每个值对,不带delimeters,然后根据我的键散列该字符串。(请再次注意,这很好)

    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;
    }
    

    1. 创建本过程后面需要的规范化查询字符串:

    a。按参数名称和自然字节顺序对UTF-8查询字符串组件进行排序。 是application/x-www-form-urlencoded)。

    不要对RFC 3986定义的任何无保留字符进行URL编码。 这些未保留的字符是A-Z、A-Z、0-9、连字符(-)、下划线(u)、句点(.), 和tilde(~)。
    大写字母A-F。
    对扩展UTF-8字符进行百分比编码,格式为%XY%ZA。。。。
    做)。


    需要对它们进行编码。但是,您可能希望包含处理参数的代码 使用保留字符的名称,以备将来使用。

    c。用等号(=)将编码参数名称与其编码值分开

    1. 根据以下伪语法创建要签名的字符串(“\n”表示 StringToSign=HTTPVerb+“\n”+ HTTPRequestURI+“\n”+
      规范化查询字符串 HTTPRequestURI组件是URI的HTTP绝对路径组件,最多为,但不是 包括查询字符串。如果HTTPRequestURI为空,请使用正斜杠(/)。
    2. 使用您刚刚创建的字符串,即您的秘密访问密钥,计算符合RFC2104的HMAC 作为密钥,SHA256或SHA1作为哈希算法。 有关更多信息,请访问 http://www.rfc.net/rfc2104.html .
    3. 将结果值转换为base64。
    4. 将结果值用作签名请求参数的值。

    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;
    }
    

      internal class CanonicalizedDictCompare : IComparer<string>
      {
        #region IComparer<string> Members
    
        public int Compare(string x, string y)
        {
          return string.CompareOrdinal(x, y);
        }
    
        #endregion
      }
    

    据我所知,我已经为这个散列做了所有我需要做的事情,但是我不断从服务器收到一个错误,告诉我我的签名不正确。救命啊。。。

    1 回复  |  直到 13 年前
        1
  •  7
  •   JulianM    13 年前

    好的,我发现了…HttpUtility类中的UrlEncoding不符合Amazon编码方案…grrr(特别是.NET实用程序中%后面的十六进制值是小写,而不是大写)

    b。URL根据以下规则对参数名称和值进行编码:

    • 不要对任何 未保留的字符 RFC 3986 定义。这些未保留的字符 是A-Z,A-Z,0-9,连字符(-), 波浪线(~)。
    • 百分比编码所有其他字符 对于%XY,其中X和Y为十六进制 大写字母A-F

    • 百分比编码扩展UTF-8 格式为%XY%ZA…的字符。。。。

    • 对空间进行百分比编码 常用的编码方案(如有)。

    因此,在编写了一个对该方案进行编码的快速方法之后,它工作得很好。