2

I had an Apex class in which I could connect to my Amazon S3 bucket by creating a request using Sig v.2 for AWS. I now need to change my code to Sig V.4 to connect to a different S3 region. I've been following the instructions on http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.htm

I get an error as follows from Amazon "The request signature we calculated does not match the signature you provided. Check your key and signing method.")

Possible Issue 1 that I can think of: I am creating my signing key incorrectly using Apex.

For Possible Issue 1 I tried to create my Signing Key using the following code

        Blob secretKeyBlob = Blob.valueOf('AWS4' + secretKey);
        Blob dateStringBlob = Blob.valueOf('20141015');
        Blob dateKeyBlob = Crypto.generateMac('hmacSHA256', dateStringBlob, secretKeyBlob);
        Blob regionBlob = Blob.valueOf('eu-west-1');
        Blob dateRegionKeyBlob = Crypto.generateMac('hmacSHA256', regionBlob, dateKeyBlob);
        Blob serviceBlob = Blob.valueOf('s3');
        Blob dateRegionServiceKeyBlob = Crypto.generateMac('hmacSHA256', serviceBlob, dateRegionKeyBlob);
        Blob requestBlob = Blob.valueOf('aws4_request');
        Blob signingKeyBlob = Crypto.generateMac('hmacSHA256', requestBlob, dateRegionServiceKeyBlob);

This is based on the hmacSHA256 signing key representation in the diagram on the page and the following sample given in the page

signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request")

Should my Apex code work correctly & similar to the pseudocode above as taken from the AWS page? I would have thought my Apex was correct.

I've no way of validating if my signing key is correct therefore I'm not sure if this is the error cause.

2
  • Were you able to get through this and find right way of signing key ? Commented May 4, 2015 at 15:12
  • Guys - Any success here ? Commented Sep 3, 2015 at 19:35

2 Answers 2

1

I was able to produce a working client with Signature Version 4 Signing by utilising the solution from this existing answer.

0

I'm using below code (to generate signature) and it's working fine in most of orgs (regions), but in few orgs this too gives error "Web service callout failed: WebService returned a SOAP Fault: The request signature we calculated does not match the signature you provided. Check your key and signing method. faultcode=soapenv:Client.SignatureDoesNotMatch faultactor="

So not sure if we can consider this 100% answer or not. Try out, maybe it works for you or help me to update this to make it work across all regions.

public string signature(string op, Datetime now) {
    //format should be  2006-01-01T12:00:00.000Z
    system.assert(this.secret != null, ' missing S3.secret key');
    String formattednow = now.formatGmt('yyyy-MM-dd') + 'T' + now.formatGmt('HH:mm:ss') + '.' + now.formatGMT('SSS') + 'Z';
    String canonical = 'AmazonS3' + op + formattednow; //"AmazonS3" + OPERATION + Timestamp              
    Blob bsig = Crypto.generateMac('HmacSHA256', Blob.valueOf(canonical), Blob.valueOf(this.secret));
    return EncodingUtil.base64Encode(bsig);
}
1
  • How do you generate String op?
    – manza
    Commented Aug 26, 2020 at 4:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .