HTML Direct Upload Data to Amazon S3 Part 2: PHP Details


Here I discuss details about application server side programming (PHP: base64 encoding, sha1 hash, .etc) to support uploading data to Amazon S3 from HTML client directly. As our task requires, we need to upload the data directly to Amazon S3 without going through our application server, and as a result, the server side would only be involved in the authenticating responsibilities to generate signature and policy in base64 format and directly put these information into the HTML page the users use to do the direct uploading.

PHP Code

$bucketname = "YourOwnBucketName";
$accesskey = "YourOwnAccessKeyID";
$secretkey = "YourOwnSecretKey";

$policy = json_encode(array(
	'expiration' => date('Y-m-d\TG:i:s\Z', strtotime('+1 hours')),
        'conditions' => array(
                        'bucket' => $bucketname
                        'acl' => 'public-read'

$base64policy = base64_encode($policy);
$base64signature = base64_encode(hash_hmac("sha1", $base64policy, $secretkey, $raw_output = true));

I will explain what exactly the code in each line does.

1) The first three lines are just specify our Amazon S3 account information, and you should already created the bucket and stored the access key and secret key somewhere secure. Just specify all these three with your own specific values;

2) We need to make our policy about what the request we send to Amazon S3 is allowed to do and is not allowed to do. This policy has to be in base64 format of json representation. So we just make our PHP array and call the library “json_encode” to returns a string containing the JSON representation.

  • in the policy, we indicate the expiration time would be in one hour after the the user get our HTML page and usually it is a good practice to restrict the latest uploading time like in our case it is one hour later. And the bucked is specified by the code in the policy which means the user cannot upload data into any other places within Amazon S3 but the bucket we designate. The acl specifies access control list and we set it as public-read in our example. You can also control the key which is the unique identifier for the object in that bucket by specifying the prefix the key or the full path of the uploaded object as indicated by “start-with”.
  • there are other more options you can specify in the policy to restrict the things the user could do who try to upload the data.

3) Base64 is just a way to represent binary data by using only 64 printable characters. This is just required by Amazon S3, nothing special and in PHP, existed library call base64_encode could do this job for us

4) hash_hmac() just enerates a keyed hash value using the HMAC method you can check PHP menu for further reference.

After knowing what all these pieces of code do, we will try to put the encrypted and encoded information in the HTML requested by the user. So next time the user want to directly upload the data, s/he does not have to interact with our application server again since s/he got all the authenticate information to upload the data legally (at least from the angle of Amazon S3).


Details about application server side programming (PHP: base64 encoding, sha1 hash, .etc) to support uploading data to Amazon S3 from HTML client directly are given and touched. Feel free to leave any comments here.

Written on October 7, 2014