Amazon AWS S4 Signature Does Not Match

I am having some issues generating a valid signature for Amazon AWS S4 using temporary access keys. I have placed my code below if anybody wouldn't mind spotting out any mistakes I may have made!

The response I am getting from their service every time is: "SignatureDoesNotMatch" = "The request signature we calculated does not match the signature you provided. Check your key and signing method".

Even when taking the suggested signature to use on the same timestamp I am getting exactly the same response.

I'm a bit stumped on this one now, was hoping to have a very simple standalone function for this but after many hours of attempting different angles I don't seem to be getting anywhere!

Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class Form1

    ' Variables
    Dim URL As String = "https://s3-us-west-2.amazonaws.com/xxx.com/CFCD208495D565EF66E7DFF9F98764DA_E0965B2E-0D0F-4CC5-B82B-AED142C3F171_p.jpg"
    Dim ProfileImagePath As String = "C:image.jpg"
    Dim AccessKeyId As String = "xxxxxxRWA52ZL6XLEA"
    Dim SessionToken As String = "xxxxx//////////wEaDBTonaKkiE9LmSoeWiLOA6.....=="
    Dim SecretAccessKey As String = "xxxxxxGzXPJ1LUp7onT3lol9Vdb3dbySN"


    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Try
            UploadImage(URL, ProfileImagePath, AccessKeyId, SessionToken, SecretAccessKey)
            MessageBox.Show("Successful")
        Catch ex As Exception
            MessageBox.Show("Failed: " & ex.Message)
        End Try
    End Sub

    Friend Function UploadImage(ByVal URL As String, ByVal FilePath As String, ByVal AccessKeyId As String, ByVal SessionToken As String, ByVal SecretAccessKey As String) As String
        ServicePointManager.ServerCertificateValidationCallback = (Function(sender, certificate, chain, sslPolicyErrors) True)
        System.Net.ServicePointManager.Expect100Continue = False
        ' Variables
        Dim CurrentDate As DateTime = DateTime.Now()
        Dim FileData As System.Drawing.Image
        Dim fs As System.IO.FileStream
        Dim Content As String = ""
        ' Set Headers To Encode
        Dim builder As StringBuilder = New StringBuilder()
        builder.Append("PUT")
        builder.Append(vbLf)
        builder.Append(Split(URL, ".amazonaws.com")(1))
        builder.Append(vbLf)
        builder.Append("host:s3-us-west-2.amazonaws.com")
        builder.Append(vbLf)
        builder.Append("x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD")
        builder.Append(vbLf)
        builder.Append("x-amz-date:" & CurrentDate.ToString("yyyyMMddTHHmmssZ"))
        builder.Append(vbLf)
        builder.Append("x-amz-security-token:" & URLEncode(SessionToken))
        builder.Append(vbLf)
        builder.Append("host;x-amz-content-sha256;x-amz-date;x-amz-security-token")
        ' Add To String
        Dim canonicalString As String = builder.ToString()
        ' Hex Encode
        Dim hashedCanonicalRequest As String = HexEncode(Hash(ToBytes(canonicalString)))
        Dim signedHeaders As String = "content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token"
        Dim stringToSign As String = "AWS4-HMAC-SHA256" & vbLf & CurrentDate.ToString("yyyyMMddTHHmmssZ") & vbLf & DateTime.Now().ToString("yyyyMMdd") & "/us-west-2/s3/aws4_request" & vbLf & hashedCanonicalRequest
        Dim signingKey As Byte() = getSignatureKey(SecretAccessKey, DateTime.Now().ToString("yyyyMMdd"), "us-west-2", "aws4_request")
        Dim StringSignature = HexEncode(HmacSha256(stringToSign, signingKey))
        ' Save Image To Memory
        Dim ms As New MemoryStream()
        Try
            fs = New System.IO.FileStream(FilePath, System.IO.FileMode.Open)
            FileData = Image.FromStream(fs)
            FileData.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
        Catch ex As Exception
            Throw New Exception("Failed To Load Image: " & ex.Message)
        End Try
        ' Variables
        Dim req As HttpWebRequest = DirectCast(WebRequest.Create(URL), HttpWebRequest)
        ' Set Request Settings
        req.Method = "PUT"
        req.Accept = "*/*"
        req.Headers("Authorization") = "AWS4-HMAC-SHA256 Credential=" & AccessKeyId & "/" & DateTime.Now().ToString("yyyyMMdd") & "/us-west-2/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=" & StringSignature
        req.Headers.Add("X-Amz-Date", CurrentDate.ToString("yyyyMMddTHHmmssZ"))
        req.UserAgent = "aws-sdk-iOS/2.2.0 iOS/10.2.1 en_GB"
        req.Headers.Add("X-Amz-Security-Token", SessionToken)
        req.ContentType = "image/jpeg"
        req.Headers.Add("x-amz-content-sha256", "STREAMING-AWS4-HMAC-SHA256-PAYLOAD")
        ' Set Bytes
        Dim imageBytes As Byte() = ms.ToArray()
        Dim postBytes As Byte() = New Byte((imageBytes.Length - 1)) {}
        req.ContentLength = postBytes.Length
        Buffer.BlockCopy(imageBytes, 0, postBytes, 0, imageBytes.Length)
        ms.Close()
        ' Get/Read Stream
        Dim postreqstream As Stream = req.GetRequestStream()
        Dim postresponse As HttpWebResponse
        postreqstream.Write(postBytes, 0, postBytes.Length)
        postreqstream.Close()
        postresponse = DirectCast(req.GetResponse(), HttpWebResponse)
        Dim postreqreader As New StreamReader(postresponse.GetResponseStream())
        Content = postreqreader.ReadToEnd
        ' Close Connection
        postresponse.Close()
        fs.Close()
        Return Content
    End Function

    Private Shared Function getSignatureKey(key As String, dateStamp As String, regionName As String, serviceName As String) As Byte()
        Dim kSecret As Byte() = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray())
        Dim kDate As Byte() = HmacSHA256(dateStamp, kSecret)
        Dim kRegion As Byte() = HmacSHA256(regionName, kDate)
        Dim kService As Byte() = HmacSHA256(serviceName, kRegion)
        Dim kSigning As Byte() = HmacSHA256("aws4_request", kService)

        Return kSigning
    End Function

    Private Shared Function ToBytes(str As String) As Byte()
        Return Encoding.UTF8.GetBytes(str.ToCharArray())
    End Function

    Private Shared Function HexEncode(bytes As Byte()) As String
        Return BitConverter.ToString(bytes).Replace("-", String.Empty).ToLowerInvariant()
    End Function

    Private Shared Function Hash(bytes As Byte()) As Byte()
        Dim sha256__1 = SHA256.Create()
        Return sha256__1.ComputeHash(bytes)
    End Function

    Private Shared Function HmacSha256(data As [String], key As Byte()) As Byte()
        Return New HMACSHA256(key).ComputeHash(ToBytes(data))
    End Function

    Friend Function URLEncode(ByVal URL As String) As String
        If URL = Nothing OrElse URL = "" Then Return ""
        Return Uri.EscapeDataString(URL)
    End Function

End Class
链接地址: http://www.djcxy.com/p/6650.html

上一篇: AWS Item LookUp URL签名

下一篇: Amazon AWS S4签名不匹配