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
Test User 15Test User 15 

AWS IAM Signature Version 4 and Canonial Request

What am I missing? Can anyone help me out.
I'm integrating Athena to Salesforce. I'm getting error:
[149]|DEBUG|Response Body<?xml version="1.0" encoding="UTF-8"?>
USER_DEBUG <Response><Errors><Error><Code>AuthFailure</Code><Message>AWS was not able to validate the provided access credentials</Message></Error></Errors><RequestID>********-****-****-****-*************</RequestID></Response>

Here is my code:
public class AWSHelper {
	 private string HTTPRequestMethod ='GET';
    private string canonicalURI = '/' ;	//since we dont have any path
    private string canonicalQueryString= 'Action=DescribeRegions&Version=2015-10-01' ;
    private string canonicalHeaders ;
    private string signedHeaders ;
    private string requestPayload;
    private string access_key ='********************';
    private string secret_key ='****************************************';
    private string service = 'iam';
    private string contentType = 'application/x-www-form-urlencoded; charset=utf-8';
    private string host = 'iam.amazonaws.com';
    private string region = 'us-east-1';
    private string endpoint = 'https://iam.amazonaws.com';
    private string request_parameters = 'Action=DescribeRegions&Version=2015-10-01&AUTHPARAMS' ; 
    // Version Dates for Different Services:-  
    // Athena Version=2017-05-18, EC2 Version=2015-10-01, IAM Version=2012-10-17
    
        	
    private string canonical_request ;
    private string algorithm = 'AWS4-HMAC-SHA256';

    public  string getISO8601DateTime(){
        return System.now().formatGMT('YYYYMMdd\'T\'HHmmss\'Z\'');
        //+ ' !!============!! ------ > '+ System.now().formatGMT('yyyyMMdd\'T\'HHmmss\'Z\''); 
    }
    
    public  string getISO8601Date(){
        return System.now().formatGMT('YYYYMMdd');
        //+ ' !!============!! ------ > '+ System.now().formatGMT('yyyyMMdd\'T\'HHmmss\'Z\''); 
    }
   
    public string payLoad(string payload){
        // in case of GET request we have empty payload
        Blob hash = Crypto.generateDigest('sha256',Blob.valueOf(payload));
        return EncodingUtil.convertToHex(hash);
    }
    
    public Blob sign(Blob key, string message){
        string algorithm='HmacSHA256';
        Blob output=Crypto.generateMac(algorithm, Blob.valueof(message), key);
        return output;
        
    }
    public  void buildCanonicalString()
    {
        Blob key=Blob.valueof('AWS4'+secret_key);
        
        
        // TASK 1
		canonicalHeaders='content-type:' + contentType + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + getISO8601DateTime() +  '\n';
        signedHeaders='content-type;host;x-amz-date';
        
        canonical_request=HTTPRequestMethod + '\n' + canonicalURI + '\n' +
            						canonicalQueryString+ '\n' +canonicalHeaders +'\n' +signedHeaders +'\n' + payload('');
        System.debug('canonical_request-->'+canonical_request);
		
        
        
		//  string hmac='SHA-256';
        Blob targetBlob = Blob.valueOf(canonical_request);
        Blob hash = Crypto.generateDigest('SHA-256', targetBlob);	//using SHA-256
        Blob hash2 = Crypto.generateMac('hmacSHA256', targetBlob, key);		//using hmacSHA256
        String canonical_request_hash = EncodingUtil.convertToHex(hash);
        String canonical_request_hash2 = EncodingUtil.convertToHex(hash2);
        
        System.debug('canonical_request_hash---->'+canonical_request_hash);
		System.debug('canonical_request_hash2---->'+canonical_request_hash2);
        
        // TASK2
        string credential_scope = getISO8601Date() + '/' + 'us-east-1' + '/' + 'ec2' + '/' + 'aws4_request\n';
        string stringToSign=algorithm + '\n' +  getISO8601DateTime() + '\n' +  credential_scope + '\n' + canonical_request_hash2;
        
        System.debug('stringToSign--->'+stringToSign);
        // task 3 Calculate the AWS Signature Version 4
        Blob keySecret = Blob.valueOf('AWS4' + secret_key);
    	Blob keyDate = Crypto.generateMac('hmacSHA256', Blob.valueOf(getISO8601Date()), keySecret);
    	Blob keyRegion = Crypto.generateMac('hmacSHA256', Blob.valueOf(region), keyDate);
    	Blob keyService = Crypto.generateMac('hmacSHA256', Blob.valueOf(service), keyRegion);
    	Blob keySigning = Crypto.generateMac('hmacSHA256', Blob.valueOf('aws4_request'), keyService);
		// string keysigningstring = EncodingUtil.convertToHex(keySigning);
        
        
         Blob blobToSign = Blob.valueOf(stringToSign); // from task 2
        Blob hmac = Crypto.generateMac('hmacSHA256', blobToSign, keySigning);
        String signature = EncodingUtil.convertToHex(hmac);
        
        
        
		/* Blob blobToSign = Blob.valueOf(stringToSign);
    	Blob blobToSignhmac = Crypto.generateMac('hmacSHA256', keySigning, blobToSign);
    	String signature = EncodingUtil.convertToHex(blobToSignhmac);
        */
        
               
		// Task 3 Calculate Signature
		//Blob signing_key =getSignatureKey (secret_key, getISO8601Date(), region, service);
        //Blob signature=sign(signing_key,stringToSign);
		//string finalSignature=EncodingUtil.convertToHex(signature).toLowerCase();
        // Task 4 Add Signining Information to Header
      
        String authorization = 'AWS4-HMAC-SHA256'
        + ' ' + 'Credential=' + access_key + '/' + credential_scope
        + ', ' + 'SignedHeaders=' + signedHeaders
        + ', ' + 'Signature=' + signature
		;
		
    	system.debug('authorization----->'+authorization);
        system.debug('getISO8601Date----->'+getISO8601Date());
		HttpRequest req = new HttpRequest();
        string endpoint= endpoint+'?'+canonicalQueryString  +
            	'&X-Amz-Algorithm=AWS4-HMAC-SHA256&'+
                    '&X-Amz-Credential='+EncodingUtil.urlEncode((access_key + '/' + credential_scope), 'UTF-8')+
                    +'&X-Amz-Date='+getISO8601Date()+
                    '&X-Amz-Expires=60'+
                    '&X-Amz-SignedHeaders='+signedHeaders+
            		'&X-Amz-Signature='+signature+
            		'&AWSAccessKeyId='+access_key;

       	req.setEndpoint(endpoint);	// Use authorization_header or querystring
        req.setMethod(HTTPRequestMethod);
		// req.setHeader('Authorization', authorization);
       	req.setHeader('content-type' , contentType);
        //req.setHeader('host','iam.amazonaws.com');
        //req.setHeader('x-amz-date',getISO8601Date());
        
		// req.setHeader('X-Amz-Credential',access_key+'/'+getISO8601Date()+'/us-east-1/s3/aws4_request');
		// req.setHeader('X-Amz-Date',getISO8601Date());
       	
        //req.setHeader('x-Amz-Host',host);
        
		// req.setHeader('X-Amz-Expires','604678');
		// req.setHeader('X-Amz-SignedHeaders','host');
		// req.setHeader('x-amz-content-sha256', 'UNSIGNED-PAYLOAD');
            
		// req.setHeader('X-Amz-Signature',finalSignature); 
		// Http ht = new Http();
		HttpResponse res = new Http().send(req);
        system.debug('endpoint'+endpoint);
		System.debug('Response Body'+res.getBody());
		//System.debug('Status'+res.getStatus());        
    }
}

Thanks in advance​​​​​​​
NagendraNagendra (Salesforce Developers) 
Hi,

Sorry for this issue you are facing.

May I suggest you please refer to below link with a similar discussion which might help you further. Hope this helps.

Kindly mark this as solved if the reply was helpful.

Thanks,
Nagendra
Test User 15Test User 15
Hi Nagendra,

I tried that link and getting this error:
 
Response Body<ErrorResponse xmlns="http://webservices.amazon.com/AWSFault/2005-15-09"> 
<Error>
<Type>Sender</Type>
<Code>InvalidAction</Code>
<Message>Could not find operation ListUsers for version 2012-10-17</Message>
</Error>
<RequestId>83702cf3-97cc-11e9-82f6-8f5e7da59408</RequestId>
</ErrorResponse>

Thanks for replying