Signature V4 AWS S3 Put C#
protected void btnSubmit_Click(object sender, EventArgs e)
{
fnPutObject();
}
string ToHex(byte[] array)
{
string strOutput = "";
for (int i = 0; i < array.Length; i++)
{
strOutput += $"{array[i]:x2}";
}
return strOutput;
}
byte[] HmacSHA256(String data, byte[] key)
{
String algorithm = "HmacSHA256";
KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
kha.Key = key;
return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}
byte[] HashFromString(String data)
{
String algorithm = "SHA256";
HashAlgorithm ha = HashAlgorithm.Create(algorithm);
return ha.ComputeHash(Encoding.UTF8.GetBytes(data));
}
byte[] HashFromByte(Byte[] data)
{
String algorithm = "SHA256";
HashAlgorithm ha = HashAlgorithm.Create(algorithm);
return ha.ComputeHash(data);
}
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;
}
void fnPutObject()
{
string strAccessKey = "";
string strSecretKey = "";
DateTime dt;
dt = DateTime.UtcNow;
string amzdate = dt.ToString("yyyyMMddTHHmmssZ");
string strDate = dt.ToString("yyyyMMdd");
string strMethod = "PUT";
string strService = "s3";
string strBucketName = "jeff";
string strHost = strBucketName + "." + strService + ".amazonaws.com";
string strRegion = "us-east-1";
string strContentName = "myfile.txt";
var byteContent = Encoding.UTF8.GetBytes("Hello World!");
string strContentType = "text/plain";
//string strAcl = "public-read"; //If no acl provided, private is used
string strPayloadHash = ToHex(HashFromByte(byteContent));
//Headers
Dictionary<<string, string> dictRequestHeaders = new Dictionary<string, string>();
dictRequestHeaders.Add("Content-Type", strContentType);
dictRequestHeaders.Add("Host", strHost);
//dictRequestHeaders.Add("x-amz-acl", strAcl);
dictRequestHeaders.Add("x-amz-content-sha256", strPayloadHash);
dictRequestHeaders.Add("x-amz-date", amzdate);
var lstCanonicalHeaders = new List<string>();
foreach (var item in dictRequestHeaders)
{
lstCanonicalHeaders.Add(item.Key.ToLower() + ":" + item.Value);
}
string strCanonicalHeaders = String.Join("\n", lstCanonicalHeaders.ToArray());
var lstSignedHeaders = new List<string>();
foreach (var item in dictRequestHeaders)
{
lstSignedHeaders.Add(item.Key.ToLower());
}
string strSignedHeaders = String.Join(";", lstSignedHeaders.ToArray());
//Canonical Request
var lstCanonicalRequest = new List<string>();
lstCanonicalRequest.Add(strMethod);
lstCanonicalRequest.Add("/" + strContentName);
lstCanonicalRequest.Add("");
lstCanonicalRequest.Add(strCanonicalHeaders);
lstCanonicalRequest.Add("");
lstCanonicalRequest.Add(strSignedHeaders);
lstCanonicalRequest.Add(strPayloadHash);
string strCanonicalRequest = String.Join("\n", lstCanonicalRequest.ToArray());
string strHashedCanonicalRequest = ToHex(HashFromString(strCanonicalRequest));
//Scope
var lstScope = new List<string>();
lstScope.Add(strDate);
lstScope.Add(strRegion);
lstScope.Add(strService);
lstScope.Add("aws4_request");
//String To Sign
var lstStringToSign = new List<string>();
lstStringToSign.Add("AWS4-HMAC-SHA256");
lstStringToSign.Add(amzdate);
lstStringToSign.Add(String.Join("/", lstScope.ToArray()));
lstStringToSign.Add(strHashedCanonicalRequest);
string strStringToSign = String.Join("\n", lstStringToSign.ToArray());
//Signature
byte[] byteSigningKey = getSignatureKey(strSecretKey, strDate, strRegion, strService);
byte[] byteSignature = HmacSHA256(strStringToSign, byteSigningKey);
string strAuthorization = "AWS4-HMAC-SHA256" + " " + "Credential=" + strAccessKey + "/" + String.Join("/", lstScope.ToArray()) + ", " + "SignedHeaders=" + strSignedHeaders + ", " + "Signature=" + ToHex(byteSignature);
string strResponse = "";
HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create("https://" + strHost + "/" + strContentName);
try
{
webReq.Headers.Add("Authorization", strAuthorization);
webReq.ContentType = strContentType;
webReq.Host = strHost;
foreach (var item in dictRequestHeaders)
{
if (item.Key.ToLower() != "content-type" AND item.Key.ToLower() != "host")
{
System.Diagnostics.Debug.WriteLine(item.Key.ToLower());
webReq.Headers.Add(item.Key, item.Value);
}
}
webReq.Method = strMethod;
Stream dataStream = webReq.GetRequestStream();
dataStream.Write(byteContent, 0, byteContent.Length);
dataStream.Close();
using (WebResponse response = webReq.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
strResponse = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
System.Diagnostics.Debug.WriteLine(strResponse);
}