Our Blog. We have some things we'd like to share.

Creating S3 URLs that expire using PHP

After reading this post on the S3 forum I realized that other people are thinking about doing some of the same stuff I have. paolonew was looking for a way to for a way to create URLs to S3 objects that expired. I did this a while back when I was thinking about how to host objects that I wanted to protect with some outside scheme. The confusion on the forum seemed to be about the timestamps used to expire the URL. For PHP it is fairly easy.

To clear up the expiration time issue I think these two steps are needed:

1) Keep in mind that the HTTP header dates must be in GMT.
2) The PHP function time() returns the seconds since the epoch January 1 1970 00:00:00 GMT). Notice here this is in GMT as well.
3) The HTTP Date header you see in a response from an S3 server is the time on that server. The machine you use to sign your request should be synced with that time. I think a good guess is that all the Amazon servers are synced with the atomic clock.

There isn’t much to securing a URL after you have that tucked away. Here is an example that will sign a URL so that it is valid for 60 seconds:

<?php

require_once('Crypt/HMAC.php');

echo getS3Redirect("/test.jpg") . "\\n";

function getS3Redirect($objectName)
{
  $S3_URL = "http://s3.amazonaws.com";
  $keyId = "your key";
  $secretKey = "your secret";
  $expires = time() + 60;
  $bucketName = "/your bucket";

  $stringToSign = "GET\\n\\n\\n$expires\\n$bucketName$objectName";
  $hasher =& new Crypt_HMAC($secretKey, "sha1");
  $sig = urlencode(hex2b64($hasher->hash($stringToSign)));

  return "$S3_URL$bucketName$objectName?AWSAccessKeyId=$keyId&Expires=$expires&Signature=$sig";
}

function hex2b64($str)
{
    $raw = '';
    for ($i=0; $i < strlen($str); $i+=2)
    {
        $raw .= chr(hexdec(substr($str, $i, 2)));
    }
    return base64_encode($raw);
}

?>

The hex2b64 function was pulled from the amazon S3 PHP example library.

Tagged:

3 Responses to “Creating S3 URLs that expire using PHP”

  1. 1

    June 1st, 2006 @ 7:59 am Paul Newman (paolonew) responded:

    Thanks for your contribution and willingness to share. Our code ended up looking very similar. Pity the S3 docs don’t expressly mention some of these finer details. I’ll ask them on the forum to do so. Cheers!

  2. 2

    May 12th, 2008 @ 9:20 am Steve responded:

    Great example, works a treat, I will be using this to protect some video content hosted on the Amazon S3 service.

    Thanks

  3. 3

    November 22nd, 2010 @ 7:45 am jbenedet responded:

    Hello, I’ve tried your code and always get the error:

    SignatureDoesNotMatch

    The request signature we calculated does not match the signature you provided. Check your key and signing method.

    What I’m doing wrong?
    Thanks

Leave a Response

Cincinnati 513.298.1865

Virginia 7875 Promontory Court Dunn Loring, VA 22027

Kentucky 12910 Shelbyville Road Suite 310 Louisville, KY 40243 502.245.6756

© 2012 Mission Data