title: AWS Signing and Javascript
body: <p>I need to send HTTP request to AWS with signed request via Javascript. Sadly I cannot use the AWS SDK JS as its either for Node.js or browser, but I need to run it from Rhino JS environment.
  seems I am doing something very wrong as I get whatever I do same result - AWS was not able to validate the provided access credentials.
   :(</p>
  
  <p>The code I am using is same as the one Amazons is using as example (but in Python). I am using only one external lib so I can use HMCA &amp;SHA. 
  Any help is much appreciated (and needed as I am struggling for days by now...), so yeah - help! </p>
  
  <p>Thanks is advance!
  Cheers,</p>
  
  <p>Joro</p>
  
  <pre><code>gs.include('jshashes');
  
  var method = 'GET';
  var service = 'ec2';
  var host = 'ec2.amazonaws.com';
  var region = 'us-east-1';
  var endpoint = 'https://ec2.amazonaws.com';
  var access_key = 'ACCESSKEY';
  var secret_key = 'SECRET/KEY';
  var request_parameters = 'AWSAccessKeyId' + access_key + 'Action=RunInstances&amp;&amp;ImageId=ami-b770fbd8';
  
  function getSignatureKey(key, date, region, service){
    var newKey = "AWS4" + key;
    var kDate = new Hashes.SHA256().b64_hmac(newKey, date); 
    var kRegion = new Hashes.SHA256().b64_hmac(kDate, region); 
    var kService = new Hashes.SHA256().b64_hmac(kRegion, service); 
    var kSigning = new Hashes.SHA256().b64_hmac(kService, "aws4_request"); 
  
    return kSigning;
  }
  
  var gdt = new GlideDateTime();
  var datestamp = gdt.getDate().getByFormat('yyyyMMdd') + 'T' + 
  gdt.getTime().getByFormat('HHmmss') + 'Z';
  var amzdate = gdt.getDate().getByFormat('yyyyMMdd')+"";
  
  var canonical_uri = '/'; 
  
  var canonical_querystring = request_parameters;
  
  var canonical_headers = 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n'
  var signed_headers = 'host;x-amz-date';
  
  var payload_hash = new Hashes.SHA256().hex(""); 
  
  var canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash;
  
  var algorithm = 'AWS4-HMAC-SHA256';
  var credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request';
  var string_to_sign = algorithm + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  new Hashes.SHA256().hex(canonical_request);
  
  var signing_key = getSignatureKey(secret_key, datestamp, region, service);
  //Python
  //var signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
  var signature = new Hashes.SHA256().hex_hmac(signing_key, string_to_sign);
  
  var authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
  
  var headers = {'x-amz-date':amzdate, 'Authorization':authorization_header}
  
  var request_url = endpoint + '?' + canonical_querystring
  
  var httpRequest = new GlideHTTPRequest(request_url);
  httpRequest.setRequestHeader(headers);
  var res = httpRequest.get();
  gs.print(res.statusCode);
  gs.print(res.allHeaders);
  gs.print(res.body);
  </code></pre>