function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Tanumay DasTanumay Das 

Unable to request Amazon MWS Error:<SignatureDoesNotMatch>

I am trying to connect to amazon MWS and fetch some report but ever time the API produces the same error  
<Code>SignatureDoesNotMatch</Code>
<Message>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.</Message>

THE CODE
Datetime now = Datetime.now().addDays(1);
    //String timestamp = now.formatGmt('yyyy-MM-dd')+'T'+now.formatGmt('HH:mm:ss')+'.'+now.formatGMT('SS')+'Z';
    String timestamp = now.formatGmt('yyyy-MM-dd')+'T'+now.formatGmt('HH:mm:ss')+'Z';
    DateTime start_dt = DateTime.newInstance(2014, 12, 16,15,21,30);
    DateTime end_dt = DateTime.newInstance(2014, 12, 18,14,17,21);
    //String start_date = start_dt.formatGmt('yyyy-MM-dd')+'T'+start_dt.formatGmt('HH:mm:ss')+'.'+start_dt.formatGMT('SS')+'Z';
    //String end_date = end_dt.formatGmt('yyyy-MM-dd')+'T'+end_dt.formatGmt('HH:mm:ss')+'.'+end_dt.formatGMT('SS')+'Z';
    String start_date = start_dt.formatGmt('yyyy-MM-dd')+'T'+start_dt.formatGmt('HH:mm:ss')+'Z';
    String end_date = end_dt.formatGmt('yyyy-MM-dd')+'T'+end_dt.formatGmt('HH:mm:ss')+'Z';

String request = 'AWSAccessKeyId='+urlencode('-***MY CODE*****-')+
            '&Action='+urlencode('RequestReport') +
            '&ReportType=' + urlencode( '_GET_MERCHANT_LISTINGS_DATA_')  +
            //'&StartDate=' + urlencode(start_date) +
            //'&EndDate=' + urlencode(end_date)+
            '&MWSAuthToken='+urlencode('-**** MY TOKEN******-')+
            //'&Marketplace='+urlencode('***ID***') +
            '&MarketplaceIdList.Id.1='+urlencode('-****ID*****-')+
            '&Merchant='+urlencode('-****ID*****-') +
            '&SignatureMethod='+urlencode('HmacSHA1') +
            '&SignatureVersion='+urlencode('2')+
            '&Timestamp=' + urlencode(timestamp) +                                                                            
            '&Version=' + urlencode('2009-01-01');


String canonical =  'GET'+'\n'+
                      'mws.amazonservices.ca\n'+
                      '/\n'+
                      request;
    String key = '-****KEY****-';
    
    //Signature HmacSHA256
    
    //Blob bsig = Crypto.generateMac('HMacSHA1', Blob.valueOf(canonical), Blob.valueOf(key));
    //Blob  b =Crypto.generateDigest('MD5',bsig );
    //Blob bsig =Crypto.generateDigest('HmacSHA256', Blob.valueOf(canonical), Blob.valueOf(key));
     //Blob bsig = Crypto.encryptWithManagedIV('AES256',  Blob.valueOf(key),Blob.valueOf(canonical));
    
    //String signature = EncodingUtil.base64encode(bsig);
    
        String c = EncodingUtil.base64Encode(Blob.valueOf(canonical));
        String signature ;
        String signingKey = EncodingUtil.base64Encode(Blob.valueOf(key));
        Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(c),blob.valueof(signingKey)); 
        signature = EncodingUtil.base64Encode(mac);                
        //return macUrl;
  
  
    System.debug('String to sign===>\n' + canonical );
    System.debug('Signature===>\n' + signature );

String body =request+'&Signature=' + urlEncode(signature);
   
   
   System.debug('canonical ===>\n' + canonical);
    System.debug('Body===>\n' + body );
   
   
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        req.setCompressed(true);
        req.setHeader('Content-Type','text/xml');
         req.setHeader('User-Agent','Salesforce');
        req.setEndpoint('https://mws.amazonservices.ca/?'+body);
        req.setMethod('GET');
        //req.setBody(body);
           
           /*req.setHeader('Host','salesforce.com');
           req.setHeader('x-amazon-user-agent','cloud/1.0');*/
      
        res = http.send(req); 
  
   
   system.debug(res.getbody());
   
   
    return null;
    
    
    
    
    }

     private String urlEncode(String rawValue) {
        String value = (rawValue == null) ? '' : rawValue;
        String encoded = null;

        try {
            encoded = EncodingUtil.urlEncode(rawValue, 'UTF-8') 
                .replace('+', '%20')
                .replace('*', '%2A')
                .replace('%7E','~');
        } catch (Exception e) {
            //System.err.println("Unknown encoding: " + CHARACTER_ENCODING);
            //e.printStackTrace();
        }

        return encoded;
    }

I have done every possible altaration on Signing algo,Url encoding as there docs but all were invain...
Jigar.LakhaniJigar.Lakhani
Hello,

Please try below code with HTTP Post request. It is working fine with me.
 
Public Void SendEmailUsingAMAZON(){
	
	String strAWSkey = 'Your Key';
	String strSecret = 'Your Secret';
	String strCurrentDateTime = DateTime.Now.formatGmt('EEE, d MMM yyyy HH:mm:ss Z');
	String strSignature = EncodingUtil.base64Encode(Crypto.generateMac('HmacSHA256', Blob.valueOf(strCurrentDateTime), Blob.valueOf(strSecret)));
	String strHeaderAuthorization = 'AWS3-HTTPS AWSAccessKeyId='+strAWSkey+', Algorithm=HmacSHA256, Signature='+strSignature;
	String strEmailBody = prepareEmailBody('List of To Addresses','Your From Address','Your Subject','Your Email Body');
	
	HttpRequest objHTTPRequest = new HttpRequest();
	objHTTPRequest.setMethod('POST');
	objHTTPRequest.setEndpoint('Your endpoint url');
	objHTTPRequest.setHeader('X-Amzn-Authorization',strHeaderAuthorization);
	objHTTPRequest.setHeader('Content-Type','application/x-www-form-urlencoded');
	objHTTPRequest.setHeader('Accept','application/xml');
	objHTTPRequest.setHeader('Date',strCurrentDateTime);
	objHTTPRequest.setBody(strEmailBody);
	
	Http objHTTP = new Http();
	
	HttpResponse objResponse = objHTTP.send(objHTTPRequest);
	String strResponseXML = objResponse.getBody();
}

private String prepareEmailBody(List<String> listToAddresses,String strFromAddres,String strSubject, String strBody) {
	String strEmailBody = 'Action=SendEmail'+'&Source='+EncodingUtil.urlEncode(strFromAddres,'UTF-8');
	for(Integer intI=1;i<listToAddresses.size()+1;intI++) {
		strEmailBody += '&Destination.ToAddresses.member.'+i+'='+EncodingUtil.urlEncode(listToAddresses[intI-1],'UTF-8');
	} 
	strEmailBody += '&Message.Subject.Data='+EncodingUtil.urlEncode(strSubject,'UTF-8') + '&Message.Body.Html.Data='+EncodingUtil.urlEncode(strBody,'UTF-8');
	return strEmailBody;
}

Thanks & Regards,
Jigar
Tanumay DasTanumay Das
Hi , Jigar

We are not tring to send email.We are trying to send a request to fetch some XML response. Simply a question to ask, is there any known issue for the generatemac function of Salesforce?

Thanks,
Tanumay
Jigar.LakhaniJigar.Lakhani
Hi,

No there is no any issue with generatemac function of salesforce.
Please try to replace your few lines with below.

Replace:
String c = EncodingUtil.base64Encode(Blob.valueOf(canonical));
String signature ;
String signingKey = EncodingUtil.base64Encode(Blob.valueOf(key));
Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(c),blob.valueof(signingKey)); 
signature = EncodingUtil.base64Encode(mac);
With Below Line:
String signature = EncodingUtil.base64Encode(Crypto.generateMac('HmacSHA256', Blob.valueOf(canonical), Blob.valueOf(Key)));

Hope it will work.

Thanks & Regards,
Jigar


 
Tanumay DasTanumay Das
Hii  we have solved the problem.. The error was due to the natural byte order (i.e-> parameters should be shorted in alfabetical order) ..the remaining part of the code is good to go...for any help mail -> tanumay.das@gmail.com
usersfdc21usersfdc21
Hi Tanumay Das,

I am trying to send data from salesforce to banking system. I am using HMACSha256.

 Blob blobSign = Crypto.generateDigest('SHA256', Blob.valueOf(privKey + xmlOutput.length() + sfTime));
        String HMACKey = EncodingUtil.base64Encode(blobSign);

I am facing the below error:
@@@Response:System.HttpResponse[Status=Forbidden, StatusCode=403]

could you please let me know is there anything wrong in my code?

Thanks in advance.
Brijesh VittalBrijesh Vittal
Hi Srikanth, Were you able to fix the issue you have posted? I'm facing the same issue.
How did you fix it?

Thanks in advance

 
KARAN SINGH 102KARAN SINGH 102
Sender 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.  IN PHP HOW TO solve the error