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.
- X-Amz-Content-Sha256
- Authorization
- 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.