'AWS API Call from GAS Signature Mismatch

I have been trying to get an api call to Amazon SES to work for sending bulk emails. After figuring out issues with dates I'm now getting an error about the signatures mismatching. My code is below

function sendEmails() {

  var template = HtmlService.createHtmlOutputFromFile('EmailTemplate.html');
  var output = template.getContent();
  var subject = 'Message from Mr. Bunz';
  var data = JSON.stringify(

    {
      "Content": { 
          "Simple": { 
            "Body": { 
                "Html": { 
                  "Data": output
                },
            },
            "Subject": { 
                "Data": subject
            }
          },
      },
      "Destination": { 
          "ToAddresses": [ "[email protected]" ]
      },
      "FromEmailAddress": "[email protected]",
      "ReplyToAddresses": [ "[email protected]" ]
    }

  );
  var url = 'https://email.us-west-1.amazonaws.com/v2/email/outbound-emails';
  var aws_key_id = 'AKIAWLG4NO6GFEXAMPLE';
  var aws_key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
  var today = new Date();
  var amz_date_iso = Utilities.formatDate(today,"UTC","YYYYMMd'T'HHmmss'Z'");
  var amz_date = Utilities.formatDate(today,"UTC",'YYYYMMd');
  console.log(amz_date)
  var signature = awsSignature(aws_key,amz_date_iso);

  var headers = {
    "contentType": "application/json",
    'X-Amz-Date': amz_date_iso,
    "Authorization": "AWS4-HMAC-SHA256 Credential="+aws_key_id+"/"+amz_date+"/us-west-1/ses/aws4_request, SignedHeaders=content-type;host;x-amz-date;, Signature="+signature
  };
  console.log(headers);
  var options = {
    
    "method": "POST",
    "headers": headers,
    "payload": data, 
    "muteHttpExceptions" : true,
  };
  apiresponse = UrlFetchApp.fetch(url,options);
  console.log(apiresponse.getContentText());    
}

function awsSignature(key,dateStamp) {
  var regionName = 'us-west-1';
  var serviceName = 'iam';

  var kDate = Utilities.computeHmacSha256Signature(dateStamp, "AWS4" + key);
  var kRegion = Utilities.computeHmacSha256Signature(
    Utilities.newBlob(regionName).getBytes(),
    kDate
  );
  var kService = Utilities.computeHmacSha256Signature(
    Utilities.newBlob(serviceName).getBytes(),
    kRegion
  );
  var kSigning = Utilities.computeHmacSha256Signature(
    Utilities.newBlob("aws4_request").getBytes(),
    kService
  );
  kSigning = kSigning
    .map(function(e) {
      return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2);
    })
    .join("");
  Logger.log(kSigning);
  return kSigning;
}

The exact error message is below

{"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."}

I've tried generating a new key/id pair with no luck. The two answers on this issue on stackoverflow I have found are here and here.

I was getting a byte array back and couldn't figure out how to convert it into the needed signature so my implementation of creating the signature is based on this post.

Would greatly appreciate any and all help.

Update After checking my signature code with the example values provided here I noticed that at the bottom where it gives the example output it says that while those are hex representations the actual signature should be binary. Now I'm having trouble converting hex to binary in GAS



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source