AWS Signature (version 4) in Apex

Here's a gist that shows the basic framework that I developed. To actually implement a sub-service using this framework, you simply need a couple of extra steps, outlined here:

public class AWSS3_GetService extends AWS {
    public override void init() {
        endpoint = new Url('https://s3.amazonaws.com/');
        resource = '/';
        region = 'us-east-1';
        service = 's3';
        accessKey = 'my-key-here';
        method = HttpMethod.XGET;
        //  You can specify "payload" here if a body is required
        //  payload = Blob.valueof('some-text');

        //  This method helps prevent leaking secret key, 
        //  as it is never serialized
        createSigningKey('my-secret-key-here');
   }
   public String[] getBuckets() {
       HttpResponse response = sendRequest();
       String[] results = new String[0];
       // Read response XML; if we get this far, no exception happened
       // This code was omitted for brevity
       return results;
   }
}

Edit: Your code looks "similar" to mine, but there's a ton of potential pitfalls. I see you're not sorting your query string correctly (as far as I can tell), and you're using the query-string version of the authorization code (which you'll see in my code is implemented as the Authorization header). The Signature query parameter itself is probably malformed; it took me quite a bit of effort (several days, in fact), to get AWS to accept a valid request from me.


The date formatting is wrong in the method "getStringToSign". The day and month must be in 2 digits, and same for hour, minutes...

You should debug your code to ensure the string to sign is in the right format (especially the date/time):

http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html