Request to Amazon SQS is failing with "SignatureDoesNotMatch" error

94 Views Asked by At

I am trying to generate the below parameters to add it in to the request header so that my request to Amazon SQS can be successful.

  1. X-Amz-Content-Sha256
  2. Authorization
  3. X-Amz-Date

For the above headers to be added in to the requests, I am writing a pre-scripts in NodeJS but I am continuously getting the "SignatureDoesNotMatch" error.

(Few more info: I am using Postman to write this pre-script to generate these headers, My Authorization Type is AWS Signature and the Access and Secret Keys are correct)

The script:

const crypto = require('crypto-js');
const moment = require('moment');

    // Derive signing key
    function getSignatureKey(key, dateStamp, regionName, serviceName) {
        var kDate = crypto.HmacSHA256("AWS4"+key, dateStamp);
        var kRegion = crypto.HmacSHA256(kDate, regionName);
        var kService = crypto.HmacSHA256(kRegion, serviceName);
        var kSigning = crypto.HmacSHA256(kService, "aws4_request");
        return kSigning;
}         
    var access_key = "AccessKey"; 
    var secret_key = "SecretKey"; 
    var method = 'POST';
    var service = 'sqs';
    var host = "sqs-endpoint";
    var region = "Region-east";
    var content_type = 'application/x-www-form-urlencoded';

    // Construct the canonical URI
    var canonical_uri = '/<<sqs_queue_name>>'; // SQS queue name 
    
    // Create a date for headers and the credential string
    var amz_date = moment().utc().format("YYYYMMDD[T]HHmmss[Z]");

    // Date in ISO8601 basic format with only date (no time)
    var date_stamp =  moment().utc().format("YYYYMMDD");

    var canonical_querystring = '';

    // Covert the hash to a hexadecimal string
    var payload = req.getBody();
    var payload_hash = crypto.SHA256(payload).toString(crypto.enc.Hex);
    
    // Sample Payload looks like below:

// {
//     "id": "ACDBJHDDL",
//     "name": "xyz",
//     "Type": "function",
//     "Number": "12345",
//     "user":"ASPD",
//     "requesteduser":"ASPD"
// }

// Construct the canonical headers
    canonical_headers = 'content-type:' + content_type + '\n' + 'host:'+ host + '\n' + 'x-amz-content-sha256:' + payload_hash + '\n' + 'x-amz-date:' + amz_date + '\n';
    
    // Construct the signed headers
    var signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date';
    
    // Construct the canonical request & hash
    var canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash; 

    var hex_canonical_request = crypto.SHA256(canonical_request).toString(crypto.enc.Hex);

    // Construct the string to sign
    var algorithm = 'AWS4-HMAC-SHA256 ';
    var credential_scope = date_stamp+'/'+region+'/'+service+'/'+'aws4_request';
    var string_to_sign = algorithm + '\n' +  amz_date + '\n' +  credential_scope + '\n' +  hex_canonical_request; 
    
    // Create the signing key using the function getSignatureKey defined above.
    var signing_key = getSignatureKey(secret_key, date_stamp, region, service);

    //Sign the string_to_sign using the signing_key
//Calculate the signature
//Covert the hash to a hexadecimal string and calculate the signature
    var signature = crypto.HmacSHA256(signing_key, string_to_sign).toString(crypto.enc.Hex);

    // Construct the authorization header
    var authorization_header = algorithm + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature;
    
    // Setting the header to send with the request
    req.setHeader("Authorization", authorization_header);
    req.setHeader("X-Amz-Content-Sha256", payload_hash);
    req.setHeader("X-Amz-Date", amz_date);
    req.setHeader("Host", host);

I have followed the AWS documentation https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html to write the script. The issue still persists.

Here is the response snippet what I am getting:

Here is what my loggings looks like:

I thing both the signature should be same what I am getting from AWS and what I am loggings. Not sure what am I missing to make it work.

0

There are 0 best solutions below