title: InvalidSignatureException Sending POST request to AWS Kinesis from SQL
body: <p>I'm trying to send data to my kinesis stream from SQL but I'm only able to get back the error.</p>
  <pre><code>{
      &quot;__type&quot;: &quot;InvalidSignatureException&quot;,
      &quot;message&quot;: &quot;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.&quot;
  }
  </code></pre>
  <p>My key &amp; secret are correct as I've done a successful test in Postman.</p>
  <p>Here is my function for creating the Authentication header...</p>
  <pre><code>ALTER FUNCTION [dbo].[CreateAuth]
  (
      @awsAccessKey NVARCHAR(MAX),
      @awsSecretKey NVARCHAR(MAX),
      @content NVARCHAR(MAX),
      @dateTime Datetime
  )
  RETURNS VARCHAR(MAX)
  AS
  BEGIN
  
      DECLARE @awsRegion NVARCHAR(MAX) = 'eu-west-2';
      DECLARE @awsService NVARCHAR(MAX) = 'kinesis';
      DECLARE @timeStamp NVARCHAR(16) = FORMAT(@dateTime, 'yyyyMMddTHHmmssZ');
      DECLARE @scope NVARCHAR(MAX) = FORMAT(@dateTime, 'yyyyMMdd') + '/'+@awsRegion+'/'+@awsService+'/aws4_request'
  
      DECLARE @x_amz_content_sha256 NVARCHAR(MAX);
      DECLARE @hexbin VARBINARY(max) =  HASHBYTES('SHA2_256 ',@content);   
  
      SET @x_amz_content_sha256 = LOWER(CONVERT([varchar](512), @hexbin,2))
      
      -- CANONICAL REQUEST
          DECLARE @CanonicalRequest NVARCHAR(MAX) = '';
          -- HTTP verb
          SET @CanonicalRequest += 'POST' + CHAR(13) 
          -- URL
          SET @CanonicalRequest += 'kinesis.eu-west-2.amazonaws.com' + CHAR(13) 
  
          -- QUERYSTRING (must be sorted alphbetically)
          SET @CanonicalRequest += '' + CHAR(13) 
  
          -- HEADERS (must be sorted alphbetically)
          SET @CanonicalRequest += 'content-type:application/x-amz-json-1.1' + CHAR(13) 
          SET @CanonicalRequest += 'host:kinesis.eu-west-2.amazonaws.com' + CHAR(13) 
          SET @CanonicalRequest += 'x-amz-content-sha256:' + @x_amz_content_sha256 + CHAR(13) 
          SET @CanonicalRequest += 'x-amz-date:' + @timeStamp + CHAR(13) 
          SET @CanonicalRequest += 'x-amz-target:' + 'Kinesis_20131202.PutRecord' + CHAR(13) 
  
          -- SIGNED HEADERS
          DECLARE @signedheaders NVARCHAR(MAX) = 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target'
          SET @CanonicalRequest += @signedheaders + CHAR(13) 
  
          -- HASHED PAYLOAD
          SET @CanonicalRequest += @x_amz_content_sha256
  
          DECLARE @CanonicalRequestHexbin VARBINARY(max) = HASHBYTES('SHA2_256 ',@CanonicalRequest);  
  
      -- STRING TO SIGN
          DECLARE @stringToSign NVARCHAR(MAX) = '';
          SET @stringToSign += 'AWS4-HMAC-SHA256' + CHAR(13) 
          SET @stringToSign += @timeStamp + CHAR(13) 
          SET @stringToSign += @scope + CHAR(13) 
          SET @stringToSign += LOWER(CONVERT([varchar](512), @CanonicalRequestHexbin,2))
  
      -- CALCULATE SIGNATURE
          DECLARE @DateKey VARBINARY(64); 
          DECLARE @DateRegionKey VARBINARY(64);
          DECLARE @DateRegionServiceKey VARBINARY(64);
          DECLARE @SigningKey VARBINARY(64);
          DECLARE @Signature VARBINARY(64);
  
          SET @DateKey                = dbo.HMAC('SHA2_256',CONVERT(VARBINARY(MAX), 'AWS4'+@awsSecretKey),CONVERT(VARBINARY(MAX),FORMAT(@dateTime, 'yyyyMMdd')))
          SET @DateRegionKey          = dbo.HMAC('SHA2_256', @DateKey,                CONVERT(VARBINARY(MAX),@awsRegion))
          SET @DateRegionServiceKey   = dbo.HMAC('SHA2_256', @DateRegionKey,          CONVERT(VARBINARY(MAX),@awsService))
          SET @SigningKey             = dbo.HMAC('SHA2_256', @DateRegionServiceKey,   CONVERT(VARBINARY(MAX),'aws4_request'))
  
          SET @Signature = dbo.HMAC('SHA2_256',@SigningKey,CONVERT(VARBINARY(MAX),@stringToSign));
  
      --BUILD Authorization
      DECLARE @AuthValue NVARCHAR(MAX) = '';
      SET @AuthValue += 'AWS4-HMAC-SHA256 Credential=' + @awsAccessKey + '/'+ @scope 
      SET @AuthValue += ',SignedHeaders=' + @signedheaders 
      SET @AuthValue += ',Signature=' + LOWER(CONVERT([varchar](512), @Signature,2))
  
      RETURN @AuthValue
  </code></pre>
  <p>And here is the call to kinesis</p>
  <pre><code>-- Open the connection.
      EXEC @ret = sp_OACreate 'MSXML2.ServerXMLHTTP', @token OUT;
      IF @ret &lt;&gt; 0 RAISERROR('Unable to open HTTP connection.', 10, 1);
  
  -- Send the request.
      EXEC @ret = sp_OAMethod @token, 'open', NULL, 'POST', @url, 'false';
      SET @auth = dbo.CreateAuth('MYACCESSKEY','MYSECRETKEY',@postData, @datetime)
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'Authorization', @auth
  
      PRINT @auth
      PRINT ''
  
      DECLARE @hexbin VARBINARY(max) =  HASHBYTES('SHA2_256 ',@postData); --hash data
      DECLARE @x_amz_content_sha256 NVARCHAR(MAX) = LOWER(CONVERT([varchar](512), @hexbin,2)) -- get hex of hashed data
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'content-type', @contentType;
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'host', 'kinesis.eu-west-2.amazonaws.com';
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-content-sha256', @x_amz_content_sha256;
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-date', @xAmzDate;
      EXEC @ret = sp_OAMethod @token, 'setRequestHeader', NULL, 'x-amz-target', @xAmzTarget;
      EXEC @ret = sp_OAMethod @token, 'send', NULL, @postData;
  
  -- Handle the response.
      EXEC @ret = sp_OAGetProperty @token, 'status', @status OUT;
      EXEC @ret = sp_OAGetProperty @token, 'statusText', @statusText OUT;
      EXEC @ret = sp_OAGetProperty @token, 'responseText', @responseText OUT;
  
  -- Show the response.
      PRINT 'Status: ' + @status + ' (' + @statusText + ')';
      PRINT 'Response text: ' + @responseText;
  
  -- Close the connection.
      EXEC @ret = sp_OADestroy @token;
      IF @ret &lt;&gt; 0 RAISERROR('Unable to close HTTP connection.', 10, 1);
  </code></pre>
  <p>The HMAC function I'm using is this one... <a href="https://gist.github.com/rmalayter/3130462" rel="nofollow noreferrer">https://gist.github.com/rmalayter/3130462</a>
  I've verified that the results produced with the SHA2_256 &amp; HMAC functions are correct using <a href="https://codebeautify.org/" rel="nofollow noreferrer">https://codebeautify.org/</a></p>
  <p>I'm pretty sure I'm doing everything according to... <a href="https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html" rel="nofollow noreferrer">https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html</a> and <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html" rel="nofollow noreferrer">https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html</a></p>
  <p>I'm lost as to what to look try next.</p>