Несоответствие подписи поиска продукта Amazon - PullRequest
0 голосов
/ 24 января 2019

Это ответ, который я получаю: рассчитанная нами подпись запроса не соответствует предоставленной вами подписи.

Вот код, который я использую для генерации подписи:

static byte[] HmacSHA256(String data, byte[] key)
{
    String algorithm = "HmacSHA256";
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
    kha.Key = key;

    return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}

static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
    byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray());
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    byte[] kSigning = HmacSHA256("aws4_request", kService);

    return kSigning;
}

Когда я использую настройки теста Amazon, я получаю правильную подпись

key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'

Однако, когда я добавляю свои живые настройки, я получаю ошибку, которая не соответствует.

Вот что я использую, чтобы получить свою подпись:

var reqSig = getSignatureKey("[my secret key]", dateStamp, "us-west-2","AWSECommerceService");

Это то, что я отправляю (сейчас я просто проверяю это в браузере):

ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[my
access key that corresponds with the secret
key]&Operation=ItemLookup&IdType=UPC&ItemId=635753490879&Timestamp=2019-01-24T19:14:55.2644840Z&Signature=32BA07ECE67F3177BF2EA02923E624D612A45FAA144ED0E43BDDC0DF6574EAC3

Я не уверен, имеет ли это отношение к региону - us-west-2 в моем случае - потому что нет места для запроса о регионе. Я не уверен, как Amazon может проверить мою подпись по моим параметрам, если я не могу указать, какой это регион, и я использовал регион для вычисления подписи.

Что мне не хватает?

1 Ответ

0 голосов
/ 26 января 2019

Хорошо. Потратив на это дни, вот что я должен был сделать:

/*

    DOCUMENTATION: https://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html#rest_detailedexample
*/

    var itemID = "0679722769";
    var accessKeyID = "AKIAIOSFODNN7EXAMPLE";
    var timeStamp = DateTime.UtcNow.ToString("o");
    var req = $"Service=AWSECommerceService&AWSAccessKeyId={accessKeyID}&Operation=ItemLookup&IdType=UPC&ItemId={itemID}&Version=2013-08-01&Timestamp={timeStamp}";
    req = req.Replace(":", "%3A").Replace(",", "%2C"); //UrlDecode certain characters
    var reqlist = req.Split('&').ToArray(); //we need to sort our key/value pairs
    Array.Sort(reqlist);
    req = String.Join("&", reqlist); //join everything back
    var reqToSign = $@"GET
webservices.amazon.com
/onca/xml
{req}".Replace("\r", ""); //create the request for signing. We need to replace microsofts's crlf with just a lf; Make sure there are no leading spaces after the linefeeds.

    var signage = getSignatureKey("1234567890",reqToSign);
    req = $"http://webservices.amazon.com/onca/xml?{req}&Signature={signage}"; //create our request with the signature appended.
    return req;
}

private static byte[] HmacSHA256(String data, byte[] key)
{
    String algorithm = "HmacSHA256";
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
    kha.Key = key;

    return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}


private static string getSignatureKey(string key, string stringToSign)
{
    byte[] kSecret = Encoding.UTF8.GetBytes(key.ToCharArray());
    byte[] kSigning = HmacSHA256(stringToSign, kSecret);
    return WebUtility.UrlEncode(Convert.ToBase64String(kSigning));
}

Вопреки большинству ответов, найденных здесь и в других местах, это единственный способ, который работает. Весь запрос должен быть хэширован, а не только конкретные параметры. Я не могу разговаривать с другими сервисами Amazon, но Commerce Service должен быть сделан следующим образом.

Несколько ответов ссылались на это: https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html или это: Amazon API, генерирующий подпись запроса в C # .NET

Как я уже говорил в своем вопросе, это, безусловно, неправильно. Если вы не передаете параметр региона, как Amazon может создать такую ​​же подпись, поскольку она не имеет всей информации.

В любом случае, это работает сейчас.

...