gpt4 book ai didi

c# - Amazon ec2 API 版本 2 签名编码与 c#

转载 作者:太空狗 更新时间:2023-10-29 21:31:37 27 4
gpt4 key购买 nike

我在为 ec2 API 的第 2 版签名编码哈希时遇到问题。

请注意,我的版本 1 签名哈希工作正常,但它已过时,我需要转到版本 2。所以首先这里是有效的代码...

parameters 只是一个字典,我所要做的只是简单地按键对参数进行排序,并附加每个值对,不带分隔符,然后根据我的键对该字符串进行哈希处理。 (再次注意,这工作正常)

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

现在,版本 2 有一些变化,这里是 API 开发人员指南中的 doco...

  1. 创建您稍后在此过程中需要的规范化查询字符串:

一个。使用自然字节顺序按参数名称对 UTF-8 查询字符串组件进行排序。参数可以来自 GET URI 或来自 POST 正文(当 Content-Type是应用程序/x-www-form-urlencoded)。

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

• 不要对 RFC 3986 定义的任何未保留字符进行 URL 编码。这些未保留的字符是 A-Z、a-z、0-9、连字符 (-)、下划线 (_)、句点 (.)、和波浪号 ( ~ )。
• 百分比使用 %XY 对所有其他字符进行编码,其中 X 和 Y 是十六进制字符 0-9 和大写 A-F。
• 百分比以 %XY%ZA 的形式编码扩展的 UTF-8 字符....
• 百分比将空格字符编码为 %20(而不是 +,作为常见的编码方案做)。

注意事项
目前所有 AWS 服务参数名称都使用非保留字符,因此您不必需要对它们进行编码。但是,您可能希望包含处理参数的代码使用保留字符的名称,以备将来使用。

使用等号 ( = ) 将编码参数名称与其编码值分开(ASCII 字符 61),即使参数值为空。

使用与符号 ( & )(ASCII 代码 38)分隔名称-值对。

  1. 根据以下伪语法创建要签名的字符串(“\n”代表ASCII 换行符)。StringToSign = HTTPVerb + "\n"+ ValueOfHostHeaderInLowercase + "\n"+ HTTPRequestURI + "\n"+
    规范化查询字符串HTTPRequestURI 组件是 URI 的 HTTP 绝对路径组件,但不是包括,查询字符串。如果 HTTPRequestURI 为空,请使用正斜杠 (/)。
  2. 使用您刚刚创建的字符串、您的 secret 访问 key 计算符合 RFC 2104 的 HMAC作为 key ,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;
}

为了完整起见,这里是 IComparer 实现....

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

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

#endregion
}

据我所知,我已经为这个散列做了我需要做的一切,但我不断收到服务器的错误消息,告诉我我的签名不正确。帮助...

最佳答案

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

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

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

  • 百分比编码扩展 UTF-8%XY%ZA.... 形式的字符

  • 百分比编码空间字符为 %20(而不是 +,因为常见的编码方案)。

所以在编写了一个编码到这个方案的快速方法之后,它工作正常。

关于c# - Amazon ec2 API 版本 2 签名编码与 c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1169817/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com