1

I have tried for quite some time to get past the irritating 'SignatureDoesNotMatch' error that Amazon keeps sending back to me from my webservice request to their API.

First, in case you are very interested in helping me but are not immediately familiar with the amazon api, here are some useful links:

  1. http://docs.aws.amazon.com/AWSECommerceService/latest/DG/ItemLookup.html (The request I'm trying to perform)
  2. http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html (The main document I used to construct my request, or attempt to)

My time-stamp declaration:

String Timestamp = datetime.now().formatGMT('yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\'');
String encoded_Timestamp = EncodingUtil.urlEncode(Timestamp, 'UTF-8');

My endpoint declaration:

String endpoint = 'http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&'+ AWSAccessKeyId=' +  (String)settings.get('Amazon_AWSAccessKeyId__c') +  '&AssociateTag=' + (String)settings.get('Amazon_Associate_ID__c') + '&Operation=ItemLookup&ItemId=' + subproduct + '&Timestamp='+encoded_Timestamp;

settings is an sObject that contains the associated values (Access key and associate ID)

I then split up and formatted the url so that it complies to the second link I posted above:

String ready_to_process = endpoint.substring(39);
String[] processing = ready_to_process.split('&');
ready_to_process = 'GET\n' + 'webservices.amazon.com\n' + '/onca/xml\n' + processing[1] + '&' + processing[2] + '&' + processing[3] + '&' + processing[4] + '&' + processing[5] + '&' + processing[0]; 

And then added the 'signature' this is the part that I am having trouble with:

endpoint += '&Signature=' + EncodingUtil.urlEncode(EncodingUtil.convertToHex(Crypto.generateMac('hmacSHA256',Blob.valueOf(ready_to_process), Blob.valueOf('**MY SECRET KEY**'))), 'UTF-8');

And I get the following error:

SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

I am very stuck and can use any assistance, guidance, directions of where to go, or anything that can help me solve why this signature creation process is wrong and how I am supposed to do it correctly. I have tried almost every relevant signature creation guideline that is found from a simple google search, this is not the only attempt.

EDIT: I found the following link: associates-amazon.s3.amazonaws.com/signed-requests/helper/index.html (add https, I can't post more than 2 links) which helps to generate the request.

From this I can tell that I put the ItemID and Operation in the incorrect spot, however after switching them it did not fix the problem.
the problem is most likely with my encryption method.

Thank you.

2
  • did you tested the procedure outside SFDC? it works using another tool that can perform the same request? it works? K.
    – Klodj_Meta
    Jun 13, 2016 at 20:47
  • I have tested off of salesforce using a PHP script on Amazon's exchange. It wasn't helpful. I've considered piping to something else to run a java script that I figure might be easier to work with. Jun 13, 2016 at 20:53

1 Answer 1

0

I worked on a similar request where in I am generating a signed URL for our customer downloads. I was also facing similar issues and most of times it is because of the string not being encoded correctly . In our use case I have stored all AWS related info in a custom setting and they are 1) Secret Key 2) Access Key

You have to generate a canonical String //generating the canonical String String stringtosign = 'GET\n\n\n'+lexpires+'\n/'+bucketname+filename; //Calling in the Generate Signature Method. String signed = GetAWSSignature(stringtosign); //Method to Generate the signature
public static string GetAWSSignature(String toSign) { String macUrl; //getting necessary info from Custom Setting
Map<string,AWS_settings__c> mapCodes2 = AWS_settings__c.getAll(); String signingKey = EncodingUtil.base64Encode(Blob.valueOf(mapCodes2.get('actifionow').Secret_Key__c)); Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(toSign), blob.valueof(mapCodes2.get('actifionow').Secret_Key__c)); macUrl = EncodingUtil.base64Encode(mac);
return macUrl; }

Once I generate the signature this way I was able to generate Signed URL's successfully .

Let me know if you need any more info .

Sarath

4
  • Doesn't amazon API require SHA256? Jun 15, 2016 at 13:46
  • Also what is the purpose of the signingKey string? It seems unused? Jun 15, 2016 at 13:47
  • Hi Konnor, yes initially i was planning to use it for URL creation but later I forgot to remove it from code. Jun 16, 2016 at 14:37
  • It looks like we need to use SHA256 as the signature that I am generating is working for our project Jun 16, 2016 at 14:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .