/// <summary> /// Computes the AWSV4 Signature and returns the Authorization value /// </summary> /// <param name="requestHeaders">Request Headers in a Dictionary</param> /// <param name="canonicalizedQueryParameters">Canonicalized Query parameters as a string, created using the <see cref="AWSv4Signer.CanonicalizeQueryParameters(string)"/> method.</param> /// <param name="serviceURL">Service Url</param> /// <param name="region">AWS Region</param> /// <param name="serviceName">Name of Service</param> /// <param name="creds">Credentials.</param> /// <param name="requestMethod">Request Method</param> /// <param name="postDataBody">Data that you want to post (if any)</param> /// <param name="requestDate">The datetime of the request</param> /// <returns>Hash of the data</returns> public string GetAWSSigV4AuthorizationValue( IDictionary <string, string> requestHeaders, string canonicalizedQueryParameters, string serviceURL, string region, string serviceName, ImmutableCredentials creds, string requestMethod, string postDataBody, DateTime requestDate) { // canonicalize headers names var canonicalizedHeaderNames = CanonicalizeHeaderNames(requestHeaders); // canonicalize headers var canonicalizedHeaders = CanonicalizeHeaders(requestHeaders); // check if query param is empty if (canonicalizedQueryParameters == null) { canonicalizedQueryParameters = string.Empty; } // hash the post data even if its empty var postDataBodyHash = string.IsNullOrEmpty(postDataBody) ? EMPTYBODYSHA256 : AWSSDKUtils.BytesToHexString(CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(Encoding.UTF8.GetBytes(postDataBody))).ToLower(); // canonicalize the request var canonicalizedRequest = CanonicalizeRequest(serviceURL, requestMethod, canonicalizedQueryParameters, canonicalizedHeaderNames, canonicalizedHeaders, postDataBodyHash); // hash the canonical request string var hashedCanonicalRequest = AWSSDKUtils.BytesToHexString(CryptoUtilFactory.CryptoInstance.ComputeSHA256Hash(Encoding.UTF8.GetBytes(canonicalizedRequest))).ToLower(); var dateStamp = requestDate.ToString("yyyyMMdd", CultureInfo.InvariantCulture); var amzDate = requestDate.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture); // Credential Scope var credentialScope = $"{dateStamp}/{region}/{serviceName}/{TERMINATOR}"; // string to sign var stringToSign = $"{SCHEME}-{ALGORITHM}\n{amzDate}\n{credentialScope}\n{hashedCanonicalRequest}"; // signature key var signingKey = GetSigningKey(region, dateStamp, serviceName, creds.SecretKey); // AWS v4 signature var signature = AWSSDKUtils.BytesToHexString(HmacSHA256(stringToSign, signingKey)).ToLower(); // create the authorization var authString = new StringBuilder(); authString.AppendFormat("{0}-{1} ", SCHEME, ALGORITHM); authString.AppendFormat("Credential={0}/{1}, ", creds.AccessKey, credentialScope); authString.AppendFormat("SignedHeaders={0}, ", canonicalizedHeaderNames); authString.AppendFormat("Signature={0}", signature); return(authString.ToString()); }
private static void CompareHashes(string etag, byte[] hash) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(etag) && !etag.Contains("-")) { etag = etag.Trim(etagTrimChars); string b = AWSSDKUtils.BytesToHexString(hash); if (!string.Equals(etag, b, StringComparison.OrdinalIgnoreCase)) { throw new AmazonClientException("Expected hash not equal to calculated hash"); } } }
// Compares ETag from S3 to calculated hash // If ETag is empty or is for a multi-part upload, no comparison is made // If ETag doesn't match the hash, an exception is thrown private static void CompareHashes(string etag, byte[] hash) { if (string.IsNullOrEmpty(etag)) { return; } // if etag contains '-' character, the file was a multi-upload and we can't // compare the etag to the hash value if (etag.Contains("-")) { return; } etag = etag.Trim(etagTrimChars); string hexHash = AWSSDKUtils.BytesToHexString(hash); if (!string.Equals(etag, hexHash, StringComparison.OrdinalIgnoreCase)) { throw new AmazonClientException("Expected hash not equal to calculated hash"); } }