public AuthenticationHeaderValue CalculateAuthorizationHeaderValue(HttpMethod httpMethod, string url, DateTime date, IDictionary <string, string> httpHeaders) { string signedHeaders; var canonicalRequestHash = CalculateCanonicalRequestHash(httpMethod, url, httpHeaders, out signedHeaders); var signingKey = CalculateSigningKey(date, ServiceName); using (var hash = new HMACSHA256(signingKey)) { var scope = $"{date:yyyyMMdd}/{AwsRegion}/{ServiceName}/aws4_request"; var stringToHash = $"AWS4-HMAC-SHA256\n{RavenAwsHelper.ConvertToString(date)}\n{scope}\n{canonicalRequestHash}"; var hashedString = hash.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)); var signature = RavenAwsHelper.ConvertToHex(hashedString); var credentials = $"{_awsAccessKey}/{date:yyyyMMdd}/{AwsRegion}/{ServiceName}/aws4_request"; return(new AuthenticationHeaderValue("AWS4-HMAC-SHA256", $"Credential={credentials},SignedHeaders={signedHeaders},Signature={signature}")); } }
private static string CalculateCanonicalRequestHash(HttpMethod httpMethod, string url, IDictionary <string, string> httpHeaders, out string signedHeaders) { var isGet = httpMethod == HttpMethods.Get; var uri = new Uri(url); var canonicalUri = uri.AbsolutePath; var query = QueryHelpers.ParseQuery(uri.Query); var canonicalQueryString = query .OrderBy(parameter => parameter.Key) .Select(parameter => parameter.Value.Aggregate((current, value) => current + $"{parameter.Key}={value.Trim()}&")) .Aggregate(string.Empty, (current, parameter) => current + parameter); if (canonicalQueryString.EndsWith("&")) { canonicalQueryString = canonicalQueryString.Substring(0, canonicalQueryString.Length - 1); } var headers = httpHeaders .Where(x => isGet == false || x.Key.StartsWith("Date", StringComparison.OrdinalIgnoreCase) == false) .OrderBy(x => x.Key); var canonicalHeaders = headers .Aggregate(string.Empty, (current, parameter) => current + $"{parameter.Key.ToLower()}:{parameter.Value.Trim()}\n"); signedHeaders = headers .Aggregate(string.Empty, (current, parameter) => current + parameter.Key.ToLower() + ";"); if (signedHeaders.EndsWith(";")) { signedHeaders = signedHeaders.Substring(0, signedHeaders.Length - 1); } using (var hash = SHA256.Create()) { var hashedPayload = httpHeaders["x-amz-content-sha256"]; var canonicalRequest = $"{httpMethod}\n{canonicalUri}\n{canonicalQueryString}\n{canonicalHeaders}\n{signedHeaders}\n{hashedPayload}"; return(RavenAwsHelper.ConvertToHex(hash.ComputeHash(Encoding.UTF8.GetBytes(canonicalRequest)))); } }