tsibelman / aws-signer-v4-dot-net

Sign HttpRequestMessage using AWS Signature v4 using request information and credentials.
Apache License 2.0
72 stars 27 forks source link

Issue create signing request with param #15

Closed Remillepattes closed 5 years ago

Remillepattes commented 5 years ago

I have a problem when i try to pass a parameter into my api call. I get this error :

SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your key and signing method.

I use this code. I want to pass the "versions" parameter.

public static async Task<HttpResponseMessage> GetVersion(string bucketName, string objectName)`
{
   return await CallWebservice(HttpMethod.Get, new Uri("https://" + bucketName + "." + service + "." + region + "." + provider + "/?versions));
}
private static readonly string region = "fr-par";
private static readonly string service = "s3";
private static readonly string provider = "scw.cloud";

private static async Task<HttpResponseMessage> CallWebservice(HttpMethod method, Uri uri, byte[] content = null)
        {
            string sha256Hash = sha256("");
            var signer = new AWS4RequestSigner(keyId, secretAccessKey);
            var request = new HttpRequestMessage
            {
                Method = method,
                RequestUri = uri 
            };

            if(content != null)
            {
                request.Content = new ByteArrayContent(content);
                sha256Hash = Hash(content);
            }

            request.Headers.Add("x-amz-content-sha256", sha256Hash);
            request = await signer.Sign(request, service, region);

            var client = new HttpClient();
            var response = await client.SendAsync(request);
            return response;
        }
        private static string Hash(byte[] bytesToHash)
        {
            SHA256 _sha256 = SHA256.Create();
            var result = _sha256.ComputeHash(bytesToHash);
            return ToHexString(result);
        }

        private static string ToHexString(byte[] array)
        {
            var hex = new StringBuilder(array.Length * 2);
            foreach (byte b in array)
            {
                hex.AppendFormat("{0:x2}", b);
            }
            return hex.ToString();
        }

        static string sha256(string randomString)
        {
            var crypt = new SHA256Managed();
            var hash = new StringBuilder();
            byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
            foreach (byte theByte in crypto)
            {
                hash.Append(theByte.ToString("x2"));
            }
            return hash.ToString();
        }

Can you please help me. Thank you

tsibelman commented 5 years ago

I think the issue is with you adding an empty string for "x-amz-content-sha256" header when you don't have a payload, I think you should not send this header in such case.

tsibelman commented 5 years ago

@RemiLou I found the issue with the query string formatting for parameters without values. I also added the creation of "x-amz-content-sha256" header internally so now you don't need to do it in your own code. Please check 0.8 version

Remillepattes commented 5 years ago

@RemiLou I found the issue with the query string formatting for parameters without values. I also added the creation of "x-amz-content-sha256" header internally so now you don't need to do it in your own code. Please check 0.8 version

Thank you, it works !