У меня возникла проблема с кодировкой хэша для версии 2 Подпись API ec2.Amazon ec2 API версии 2 подписи с C#
Примечание моя версия 1 Подпись хеширование работает отлично, но это амортизируется, и мне нужно будет перейти к версии 2. Так, во-первых здесь есть код, который работает ...
параметры просто словарь, что я нужно просто отсортировать параметры по ключу и добавить каждую пару значений без разделителей, а затем хэш этой строки против моего ключа. (Опять же, обратите внимание, это работает отлично)
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 есть некоторые изменения, вот DOCO от руководства разработчиков API ...
- Создайте канонизированную строку запроса, вам необходимо позднее в этой процедуре:
a. Сортируйте компоненты строки запроса UTF-8 по имени параметра с естественным порядком байтов. Параметры могут быть получены из URI GET или из тела POST (когда Content-Type является приложением/x-www-form-urlencoded).
b. URL-адрес кодирует имя и значения параметров в соответствии со следующими правилами:
• Не кодируйте URL-код любого из безоговорочных символов, определенных в RFC 3986. Эти незаслуженные символы: A-Z, a-z, 0-9, дефис (-), подчеркивание (_), период (.), и тильда (~).
• Процент кодирует все остальные символы с% XY, где X и Y являются шестнадцатеричными символами 0-9 и прописными буквами A-F.
• Процент кодирует расширенные символы UTF-8 в форме% XY% ZA ....
• Процент кодирует пробельный символ как% 20 (и не +, как схемы общего кодирования do).
Примечание
В настоящее время все имена параметров службы AWS используют незарезервированные символы, поэтому вам не нужно кодировать их . Однако вы можете включить код для обработки параметров имен, в которых используются зарезервированные символы, для возможного использования в будущем.
c. Отделите имена закодированных параметров от их закодированных значений знаком равенства (=) (символ ASCII 61), даже если значение параметра пуст.
d. Отделите пары имя-значение амперсандом (&) (код ASCII 38).
- Создайте строку для подписи согласно следующей псевдограмматике («\ n» представляет строку новой строки ASCII ). StringToSign = HTTPVerb + "\ п" + ValueOfHostHeaderInLowercase + "\ п" + HTTPRequestURI + "\ п" +
CanonicalizedQueryString Компонент HTTPRequestURI является HTTP-абсолютный путь компонента URI до, но не в том числе, строка запроса. Если HTTPRequestURI пуст, используйте косую черту (/). - Рассчитайте HMAC, совместимый с RFC 2104, только что созданной вами строкой, ключ секретного доступа в качестве ключа и 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;
}
для полноты здесь является реализация IComparer ....
internal class CanonicalizedDictCompare : IComparer<string>
{
#region IComparer<string> Members
public int Compare(string x, string y)
{
return string.CompareOrdinal(x, y);
}
#endregion
}
Насколько я могу сказать, что я сделал все, Мне нужно сделать для этого хеша, но я все время получаю сообщение об ошибке с сервера, сообщая мне, что моя подпись неверна. Помогите ...
Класс в приведенном выше примере будет иметь: с использованием System.Security.Cryptography; Кроме того, для описания Amazon о том, как это сделать (минус вычисление хэша), см. Http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?rest-signature.html – adinas