I’ve tried everything here, but the Amazon Load Balancer API just will not accept my signature.
Whatever I try, I get a “403 SignatureDoesNotMatch” response. I’m probably missing something obvious, but having spent hours trying to figure out what that is, I’m at the end of my tether. Please help!! Thanks.
Here’s my code:
Public Sub DeregisterInstanceFromLoadBalance(ByVal strServerID As String)
Dim strURL As String
strURL = "http://elasticloadbalancing.amazonaws.com/?"
Dim strTimestamp As String = PercentEncodeRfc3986(DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'"))
Dim strParams As String
strParams = "AWSAccessKeyId=<MY_API_KEY>" & _
"&Action=DeregisterInstancesFromLoadBalancer" & _
"&Instances.member.N=" & strServerID & _
"&LoadBalancerName=ATTB" & _
"&SignatureMethod=HmacSHA256" & _
"&SignatureVersion=2" & _
"&Timestamp=" & strTimestamp & _
"&Version=2009-05-15"
Dim strStringToSign As String = "GET\nelasticloadbalancing.amazonaws.com\n/\n" & strParams
strURL = strURL & strParams & "&Signature=" & PercentEncodeRfc3986(HashString(strStringToSign))
Dim wc As New WebClient()
Dim strResponse As String
strResponse = wc.DownloadString(strURL)
End Sub
Private Const PRIVATE_KEY As String = "<MY_PRIVATE_KEY>"
Private Function HashString(ByVal StringToHash As String) As String
Dim Key() As Byte = Encoding.UTF8.GetBytes(PRIVATE_KEY)
Dim XML() As Byte = Encoding.UTF8.GetBytes(StringToHash)
Dim myHMACSHA256 As New System.Security.Cryptography.HMACSHA256(Key)
Dim HashCode As Byte() = myHMACSHA256.ComputeHash(XML)
Return Convert.ToBase64String(HashCode)
End Function
Private Function PercentEncodeRfc3986(ByVal str As String) As String
str = HttpUtility.UrlEncode(str, System.Text.Encoding.UTF8)
str = str.Replace("'", "%27").Replace("(", "%28").Replace(")", "%29").Replace("*", "%2A").Replace("!", "%21").Replace("%7e", "~").Replace("+", "%20").Replace("%7E", "~")
Dim sbuilder As StringBuilder = New StringBuilder(str)
For i As Int32 = 0 To sbuilder.Length - 1
If sbuilder(i) = "%" Then
If (Char.IsLetter(sbuilder(i + 1)) OrElse Char.IsLetter(sbuilder(i + 2))) Then
sbuilder(i + 1) = Char.ToUpper(sbuilder(i + 1))
sbuilder(i + 2) = Char.ToUpper(sbuilder(i + 2))
End If
End If
Next
Return sbuilder.ToString()
End Function
Ok, I got to the bottom of this. There were a few problems; not least Amazon’s documentation.
is just wrong, it should be
Instances.member.[N].InstanceId, where [N] is the instance index,
starting at 1. This was returning
the rather confusing error message
“LoadBalancerNotFound”.