2

edit 2: i deleted the filed awskeyid - so now s3 accepts the x-amz-signature field, but now i get back an error that : The request signature we calculated does not match the signature you provided. Check your key and signing method

so u guess im calculating the signature wrong , any ideas?

edit: I have edited the code according to the documnation i found, i think im calculating the signature right, but it still doesnt work, when I put it in the form in a field named "signature" i get an error back that this mechanism isnt supoorted and i should use the new one, but if i change the name of signature field to x-amz-signature i get back an error that there is no field named "signature"

i have a working form to upload a file directly from browser to amazon s3, i have switched my bucket to frankfurt region which dosnt support the old policy signing.

so i triued to edit my form and the policy created , but with nu luck any help will be appreciated

this is my policy:

    $policy = json_encode(array(
            'expiration' => date('Y-m-d\TG:i:s\Z', strtotime('+6 hours')),
            'conditions' => array(
                    array(
                            'bucket' => $data['bucket']
                    ),
                    array(
                            'acl' => 'private'
                    ),
                    array(
                            'starts-with',
                            '$key',
                            'Zips/Uploads'
                    ),
                    array(
                            'content-length-range', 0, 500000000
                    ),
                    array(
                            "x-amz-algorithm"=> "AWS4-HMAC-SHA256"
                    ),
                    array (
                            "x-amz-credential"=> AMAZON_KEY."/20160111/eu-central-1/s3/aws4_request"
                    ),
                    array(
                            "x-amz-date"=> "20151101T000000Z"
                    ),

                )

    ));

    $data['base64Policy'] = base64_encode($policy);
    $signing_key1 = hash_hmac('sha256', "AWS4" .AMAZON_SECRET_KEY , "20151101", true);
    $signing_key2 = hash_hmac('sha256', $signing_key1, AMAZON_REGION,true); 
    $signing_key3 = hash_hmac('sha256', $signing_key2, "s3",true);
    $signing_key4 = hash_hmac('sha256', $signing_key3, "aws4_request",true);x
    $data['signature'] = base64_encode(hash_hmac('sha256',$signing_key4, $data['base64Policy'],true));

and this is the form I'm using

<form class="startfileupload" action="//s3.eu-central-1.amazonaws.com/<?php echo $bucket; ?>/" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="${filename}" /><br />
<input type="hidden" name="acl" value="private" />
<input type="hidden" name="X-amz-Algorithm" value="AWS4-HMAC-SHA256" />
<input type="hidden" name="X-Amz-Credential" value="<?php echo $accesskey; ?>/20160111/eu-central-1/s3/aws4_request" />
<input type="hidden" name="X-Amz-Date" value="20151101T000000Z" />
<input type="hidden" name="policy" value="<?php echo $base64Policy; ?>">
<input type="hidden" name="X-Amz-Signature" value="<?php echo $signature; ?>">
<input type="file" name="file" /> <br />

using this form im getting back an error from amazon:

InvalidRequestThe authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.

what am i doing wrong? I tried reding the documantion and examples, but didnt really got me far.

thx!

8
  • S3 moved from Signature v2 to Signature v4 a little while back, so the code that signs the request needs to be updated. Are you using the official SDK? They handle all of this for you. Commented Jan 11, 2015 at 0:21
  • This question appears to be off-topic because it is about a code snippet written for V2, which will require a substantial rewrite in order to match the documented requirements for V4 authentication of POST uploads: docs.aws.amazon.com/AmazonS3/latest/API/… Commented Jan 11, 2015 at 1:24
  • I got both the official and the laravel sdk for aws, i read the documantion but still find it very hard to understand how to create my policy Commented Jan 11, 2015 at 14:57
  • @RyanParman i cant find how does the official sdk handles that for me? Commented Jan 11, 2015 at 16:04
  • Look at github.com/aws/aws-sdk-php/blob/master/src/Aws/S3/Model/… Commented Jan 12, 2015 at 19:47

1 Answer 1

2

According to this answer (Java version):

Using some help I've found the answer, which was a combination of 2 missing pieces (one of which was referred to in the comments):

1) Need to set this:

System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");

2) Must set the "endPoint" (which was not required for upload or download):

s3Client.setEndpoint(endpoint);

Optionally it might be useful to also add this:

s3Client.setS3ClientOptions(new S3ClientOptions().withPathStyleAccess(true));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.