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 ? May 4 '15 at 15:12
  • Guys - Any success here ? Sep 3 '15 at 19:35
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
    Aug 26 '20 at 4:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.