AWS SDK VS requests-aws4auth

Compare AWS SDK vs requests-aws4auth and see what are their differences.

AWS SDK

The official AWS SDK for .NET. For more information on the AWS SDK for .NET, see our web site: (by aws)

requests-aws4auth

Amazon Web Services version 4 authentication for the Python Requests module (by tedder)
Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
AWS SDK requests-aws4auth
13 1
2,006 174
0.6% -
9.9 2.8
1 day ago 11 months ago
C# Python
Apache License 2.0 MIT License
The number of mentions indicates the total number of mentions that we've tracked plus the number of user suggested alternatives.
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.

AWS SDK

Posts with mentions or reviews of AWS SDK. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2021-05-11.

requests-aws4auth

Posts with mentions or reviews of requests-aws4auth. We have used some of these posts to build our list of alternatives and similar projects. The last one was on 2021-02-25.
  • AWS S3 Raw Authentication written in C#
    2 projects | dev.to | 25 Feb 2021
    using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; namespace Storage.IO.Files.Impl.Amazon { /// /// https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html /// /// explore python version: https://github.com/tedder/requests-aws4auth /// class S3AuthHandler : DelegatingHandler { private readonly string _accessKeyId; private readonly string _secretAccessKey; private readonly string _region; private readonly string _service; private static readonly string EmptySha256 = new byte[0].SHA256().ToHexString(); public S3AuthHandler(string accessKeyId, string secretAccessKey, string region, string service = "s3") : base(new HttpClientHandler()) { _accessKeyId = accessKeyId; _secretAccessKey = secretAccessKey; _region = region; _service = service; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { await SignAsync(request); return await base.SendAsync(request, cancellationToken); } protected async Task SignAsync(HttpRequestMessage request, DateTimeOffset? signDate = null) { // a very helpful article on S3 auth: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html DateTimeOffset dateToUse = signDate ?? DateTimeOffset.UtcNow; string nowDate = dateToUse.ToString("yyyyMMdd"); string amzNowDate = GetAmzDate(dateToUse); request.Headers.Add("x-amz-date", amzNowDate); // 1. Create a canonical request /* * \n * \n * \n * \n * \n * */ string payloadHash = await AddPayloadHashHeader(request); string canonicalRequest = request.Method + "\n" + GetCanonicalUri(request) + "\n" + // CanonicalURI GetCanonicalQueryString(request) + "\n" + GetCanonicalHeaders(request, out string signedHeaders) + "\n" + // ends up with two newlines which is expected signedHeaders + "\n" + payloadHash; // 2. Create a string to sign // step by step instructions: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html /* * StringToSign = * Algorithm + \n + * RequestDateTime + \n + * CredentialScope + \n + * HashedCanonicalRequest */ string stringToSign = "AWS4-HMAC-SHA256\n" + amzNowDate + "\n" + nowDate + "/" + _region + "/s3/aws4_request\n" + canonicalRequest.SHA256(); // 3. Calculate Signature /* * DateKey = HMAC-SHA256("AWS4"+"", "") * DateRegionKey = HMAC-SHA256(, "") * DateRegionServiceKey = HMAC-SHA256(, "") * SigningKey = HMAC-SHA256(, "aws4_request") */ byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + _secretAccessKey).ToCharArray()); byte[] kDate = HmacSha256(nowDate, kSecret); byte[] kRegion = HmacSha256(_region, kDate); byte[] kService = HmacSha256(_service, kRegion); byte[] kSigning = HmacSha256("aws4_request", kService); // final signature byte[] signatureRaw = HmacSha256(stringToSign, kSigning); string signature = signatureRaw.ToHexString(); string auth = $"Credential={_accessKeyId}/{nowDate}/{_region}/s3/aws4_request,SignedHeaders={signedHeaders},Signature={signature}"; request.Headers.Authorization = new AuthenticationHeaderValue("AWS4-HMAC-SHA256", auth); return signature; } private static string GetAmzDate(DateTimeOffset date) { return date.ToString("yyyyMMddTHHmmssZ"); } private string GetCanonicalUri(HttpRequestMessage request) { string path = request.RequestUri.AbsolutePath.TrimStart('/'); return "/" + path.UrlEncode(); } private string GetCanonicalQueryString(HttpRequestMessage request) { /** * CanonicalQueryString specifies the URI-encoded query string parameters. You URI-encode name and values individually. You must also sort the parameters in the canonical query string alphabetically by key name. The sorting occurs after encoding. */ NameValueCollection values = HttpUtility.ParseQueryString(request.RequestUri.Query); var sb = new StringBuilder(); foreach(string key in values.AllKeys.OrderBy(k => k)) { if(sb.Length > 0) { sb.Append('&'); } string value = HttpUtility.UrlEncode(values[key]); if(key == null) { sb .Append(value) .Append("="); } else { sb .Append(HttpUtility.UrlEncode(key.ToLower())) .Append("=") .Append(value); } } return sb.ToString(); } private string GetCanonicalHeaders(HttpRequestMessage request, out string signedHeaders) { // List of request headers with their values. // Individual header name and value pairs are separated by the newline character ("\n"). // Header names must be in lowercase. You must sort the header names alphabetically to construct the string. // Note that I add some headers manually, but preserve sorting order in the actual code. var headers = from kvp in request.Headers where kvp.Key.StartsWith("x-amz-", StringComparison.OrdinalIgnoreCase) orderby kvp.Key select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value }; var sb = new StringBuilder(); var signedHeadersList = new List(); // The CanonicalHeaders list must include the following: // - HTTP host header. // - If the Content-Type header is present in the request, you must add it to the CanonicalHeaders list. // - Any x-amz-* headers that you plan to include in your request must also be added. For example, if you are using temporary security credentials, you need to include x-amz-security-token in your request. You must add this header in the list of CanonicalHeaders. if(request.Headers.Contains("date")) { sb.Append("date:").Append(request.Headers.GetValues("date").First()).Append("\n"); signedHeadersList.Add("date"); } sb.Append("host:").Append(request.RequestUri.Host).Append("\n"); signedHeadersList.Add("host"); string contentType = request.Content?.Headers.ContentType?.ToString(); if(contentType != null) { sb.Append("content-type:").Append(contentType).Append("\n"); signedHeadersList.Add("content-type"); } if(request.Headers.Contains("range")) { sb.Append("range:").Append(request.Headers.GetValues("range").First()).Append("\n"); signedHeadersList.Add("range"); } // Create the string in the right format; this is what makes the headers "canonicalized" -- // it means put in a standard format. http://en.wikipedia.org/wiki/Canonicalization foreach(var kvp in headers) { sb.Append(kvp.Key).Append(":"); signedHeadersList.Add(kvp.Key); foreach(string hv in kvp.Value) { sb.Append(hv); } sb.Append("\n"); } signedHeaders = string.Join(";", signedHeadersList); return sb.ToString(); } /// /// Hex(SHA256Hash()) /// /// /// private async Task AddPayloadHashHeader(HttpRequestMessage request) { string hash; if(request.Content != null) { byte[] content = await request.Content.ReadAsByteArrayAsync(); hash = content.SHA256().ToHexString(); } else { hash = EmptySha256; } request.Headers.Add("x-amz-content-sha256", hash); return hash; } private static byte[] HmacSha256(string data, byte[] key) { var alg = KeyedHashAlgorithm.Create("HmacSHA256"); alg.Key = key; return alg.ComputeHash(Encoding.UTF8.GetBytes(data)); } } }

What are some alternatives?

When comparing AWS SDK and requests-aws4auth you can also consider the following projects:

Azure PowerShell - Microsoft Azure PowerShell

Bot Builder SDK - Bot Framework provides the most comprehensive experience for building conversation applications.

DropNet - Client Library for the Dropbox API

Octokit.NET - A GitHub API client library for .NET

Getty Images API SDK - Getty Images API SDK - .NET

Dropbox.NET - The Official Dropbox API V2 SDK for .NET

EfficientDynamoDb - High-performance C# DynamoDb library

Countly SDK for Windows - Windows Phone & Windows SDK for Countly Analytics

SharpLab - .NET language playground