title: Retrieving book details by ISBN through Amazon AWS Product Advertising API using .NET
body: <p>I wish to retrieve book details (in XML) from Amazon Web Services (AWS) Product Advertising API by sending a (conceptually) simple request containing the ISBN number of the book from a VB.NET program.  I have an Amazon AWS Account with an AWS Access Key and Secret key.</p>
  
  <p>I can get to the stage of accessing AWS, but get the following response :</p>
  
  <pre><code>  &lt;?xml version="1.0"?&gt;
    &lt;ItemLookupErrorResponse xmlns="http://ecs.amazonaws.com/doc/2005-10-05/"&gt;
    &lt;Error&gt;&lt;Code&gt;SignatureDoesNotMatch&lt;/Code&gt;&lt;Message&gt;The request signature we calculated does not
    match the signature you provided. Check your AWS Secret Access Key and signing method. Consult
    the &gt;service documentation for details.&lt;/Message&gt;&lt;/Error&gt;
    &lt;RequestId&gt;556dafef-b59f-4829-8ffe-80668cea9707&lt;/RequestId&gt;
    &lt;/ItemLookupErrorResponse&gt;
  </code></pre>
  
  <p>The code I am using is as follows (here the real Access key and Secret key have been replaced by dummy strings) :</p>
  
  <pre><code>Public Shared Function MakeRequestString(IsbnString As String) As String
  
      Dim stringToSign, strTimestamp, strSignature, strSignedRequest, strParamValuePairs As String
  
      stringToSign = "GET" &amp; vbLf   'vbLf is Line feed character Ascii 10
  
      stringToSign &amp;= "webservices.amazon.com" &amp; vbLf
  
      stringToSign &amp;= "/onca/xml" &amp; vbLf
  
      '-----------------------------------------------------------------------
  
      strParamValuePairs = "AWSAccessKeyId=" &amp; GetAWSAccessKey()
  
      strParamValuePairs &amp;= "&amp;IdType=ISBN"
  
      strParamValuePairs &amp;= "&amp;ItemId=" &amp; IsbnString
  
      strParamValuePairs &amp;= "&amp;Operation=ItemLookup"
  
      strParamValuePairs &amp;= "&amp;Service=AWSECommerceService"
  
      strTimestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff")
  
      strParamValuePairs &amp;= "&amp;Timestamp=" &amp; UrlEncode(strTimestamp)
  
      stringToSign = stringToSign &amp; strParamValuePairs
  
      '---------------------------------------------------------------
      strSignature = MakeSignature(stringToSign)
     '----------------------------------------------------
  
      strSignedRequest = "http://webservices.amazon.com/onca/xml?"
  
      strSignedRequest &amp;= "AWSAccessKeyId=" &amp; GetAWSAccessKey()
  
      strSignedRequest &amp;= "&amp;IdType=ISBN"
  
      strSignedRequest &amp;= "&amp;ItemId=" &amp; IsbnString
  
      strSignedRequest &amp;= "&amp;Operation=ItemLookup"
  
      strSignedRequest &amp;= "&amp;Service=AWSECommerceService"
  
      strSignedRequest &amp;= "&amp;Signature=" &amp; UrlEncode(strSignature)
  
      strSignedRequest &amp;= "&amp;Timestamp=" &amp; UrlEncode(strTimestamp)
  
      Return strSignedRequest
  
  End Function
  
  
  Private Shared Function MakeSignature(ByVal StringToHash As String) As String
  
      Dim myEncoder As New System.Text.UTF8Encoding
  
      Dim strSecretAccessKey As String = GetSecretKey()
  
      Dim Key As Byte() = myEncoder.GetBytes(strSecretAccessKey)
  
      Dim bytStringToHashAsBytes As Byte() = myEncoder.GetBytes(StringToHash)
  
      Dim myHMACSHA256 As New System.Security.Cryptography.HMACSHA256(Key)
  
      Dim HashCode As Byte() = myHMACSHA256.ComputeHash(bytStringToHashAsBytes)
  
      Return Convert.ToBase64String(HashCode)
  
  End Function
  
  
  Private Shared Function GetSecretKey() As String
  
      Return "AAAAAAA Secret Key AAAAAAA"
  
  End Function
  
  
  Private Shared Function GetAWSAccessKey() As String
  
      Return "AAAA Access Key AAAAA"
  
  End Function
  </code></pre>
  
  <p>To assemble the above code I have followed the Amazon AWS Product Advertising API Developer Guide Example Rest Requests (<a href="http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html" rel="nofollow">http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html</a>)</p>
  
  <p>Note, in these guidelines (Step 9) after generating the signature, the instructions are to URL encode the plus (+) and equal (=) characters in the signature, and then include such a URL encoded signature in the signed request - however in the example they are using in the guidelines they seem to URL encode other characters in the signature such as the forward slash character.  I have experimented with the URL encoding but to no avail.</p>
  
  <p>As regards URL encoding, some of the parameters do not contain any potentially problematic characters, this includes the AWS Access Key.  The Timestamp contains - and : characters, the Secret key seems to always have a forward slash (/) character in it.  The calculated signature will have special characters in it.</p>
  
  <p>I note that if you include a space in the timestamp, then the request does not proceed to the stage of returning an AWS error, but an error that the webpage cannot be found (hence the T between the date and the time in the timestamp).</p>