注意,我的第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;
}
-
创建本过程后面需要的规范化查询字符串:
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。用等号(=)将编码参数名称与其编码值分开
-
根据以下伪语法创建要签名的字符串(“\n”表示
StringToSign=HTTPVerb+“\n”+
HTTPRequestURI+“\n”+
规范化查询字符串
HTTPRequestURI组件是URI的HTTP绝对路径组件,最多为,但不是
包括查询字符串。如果HTTPRequestURI为空,请使用正斜杠(/)。
-
使用您刚刚创建的字符串,即您的秘密访问密钥,计算符合RFC2104的HMAC
作为密钥,SHA256或SHA1作为哈希算法。
有关更多信息,请访问
http://www.rfc.net/rfc2104.html
.
-
将结果值转换为base64。
-
将结果值用作签名请求参数的值。
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
}
据我所知,我已经为这个散列做了所有我需要做的事情,但是我不断从服务器收到一个错误,告诉我我的签名不正确。救命啊。。。