Discussion Forums



Thread: PHP: S3 Signature for URL

Welcome, Guest Help
Login Login


Permlink Replies: 8 - Pages: 1 - Last Post: Jun 19, 2009 7:52 AM by: Colin Rhodes
Adam Barrett
RealName(TM)

Posts: 16
Registered: 2/14/08
PHP: S3 Signature for URL
Posted: Mar 11, 2008 2:03 PM PDT
  Click to reply to this thread Reply

Here is my code:

$fileName = str_replace($this->userFilter, '', $file['name']);
$expires = time() + (60*60*12);
$stringToSign = "GET\n\n\n{$expires}\n{$file['name']}";
$hasher = new Crypt_HMAC($this->S3->_secret, 'sha1');
$signature = $this->S3->base64($hasher->hash($stringToSign));
$url = " http://s3.amazonaws.com/fdd.userimages/{$file['name']}?AWSAccessKeyId={$this->S3->_key}&Expires={$expires}&Signature={$signature}";

Amazon keeps telling me my Signature doesn't match.


---------------------
Here is the base64 function:

function base64($str)
{
     $ret = "";
     for($i = 0; $i < strlen($str); $i += 2)
          $ret .= chr(hexdec(substr($str, $i, 2)));
     return base64_encode($ret);
}


oxhlodo

Posts: 8
Registered: 3/14/08
Re: PHP: S3 Signature for URL
Posted: Mar 16, 2008 7:56 AM PDT   in response to: Adam Barrett
  Click to reply to this thread Reply

This is what I have in perl, and it works great:

use MIME::Base64        qw(encode_base64);
use Digest::SHA1        qw(sha1);
use Digest::HMAC        qw(hmac);
use URI::Escape         qw(uri_escape);

my $time_to_expire      = 60; # 1 minute

my $private_key   = '<PRIVATE_KEY>';
my $access_key          = '<ACCESS_KEY>';
my $base_url            = ' http://s3.amazonaws.com';
my $expiry              = time()+$time_to_expire;
my $bucket_name         = '<BUCKET>';
my $object_name         = uri_escape('<KEY>');
my $stringToSign        = "GET\n\n\n$expiry\n/$bucket_name/$object_name";
my $signature           = uri_escape(encode_base64(hmac($stringToSign, $private_key, \&sha1),''));
my $url                 = "$base_url/$bucket_name/$object_name?AWSAccessKeyId=$access_key&Expires=$expiry&Signature=$signature";
print "URL: $url\n";

redactingMessage was edited by: oxhlodo fix Message was edited by: oxhlodo

Allen

Posts: 5,320
Registered: 3/19/07
Re: PHP: S3 Signature for URL
Posted: Mar 17, 2008 5:22 AM PDT   in response to: Adam Barrett
  Click to reply to this thread Reply

The body of the response from S3 should contain more info about the error.


pesilatmcasto

Posts: 1
Registered: 3/31/08
Re: PHP: S3 Signature for URL
Posted: Mar 31, 2008 1:48 AM PDT   in response to: Adam Barrett
  Click to reply to this thread Reply

Here's the PHP code I used and it works perfect:

$accessKey = "<ACCESS KEY>";
$secretKey = "<SECRET KEY>";
$bucket = "<BUCKET>";
$item = "<OBJECT>";

$timestamp = strtotime("+3 days");
$strtosign = "GET\n\n\n$timestamp\n/$bucket/$item";

$signature = urlencode(base64_encode(hash_hmac("sha1", utf8_encode($strtosign), $secretKey, true)));

$url = " http://s3.amazonaws.com/$bucket/$item?AWSAccessKeyId=$accessKey&Expires=$timestamp&Signature=$signature";

print "<a href='$url'>$url</a>";


Here, in fact, is a URL generated from this code (with my live data and a different expiration, of course, so it will actually work until Mar 31, 2001 04:38:01 -0400 when it expires):

http://s3.amazonaws.com/sikaltactical.archive/supersonic_guru.flv?AWSAccessKeyId=1R8S4XZMXHXRR2XEG902&Expires=1301560681&Signature=ytBYHZoresaPx0qg9MlzDVPaMyk%3D


I initially had a problem where it didn't recognize my signature. Turns out that my "String To Sign" was sending the human readable date (i.e.: Tue, 27 Mar 2007 19:36:42 +0000)

I got this from the s3 developer's guide and it didn't give any real specifics on formatting the string.

When I submitted the resulting query I got an "Invalid Date" error. Once I changed it to use the actual timestamp it worked fine.

Hope this helps, Mike



fchristant

Posts: 14
Registered: 12/24/08
Re: PHP: S3 Signature for URL
Posted: Dec 24, 2008 4:32 AM PST   in response to: pesilatmcasto
  Click to reply to this thread Reply

Mike,

Thank you so much! That worked like a charm!

One remark though, simply because I'm curious...

I'm finding it somewhat strange that the expiration timestamp is included in the querystring. This invited me to tamper with it, to see if I could hack the URL and extend the expiration date. Luckily, this does not work. From the look of your code, the timestamp is part of the signature that is calculated. That kind of explains it, but only after investigating it, at a first glance the URL looks hackable, don't you think?


andrewslaterpresents

Posts: 10
Registered: 1/7/09
Re: PHP: S3 Signature for URL
Posted: Jan 7, 2009 3:47 AM PST   in response to: fchristant
  Click to reply to this thread Reply

This code should be plastered on the top :)

As someone who doesn't know THAT much about programming - only what I've learned to get done what I need to get done, this code is perfect. I wish I had found it 3 hours ago when I started my search for something like it!

ANdrew

mtranda

Posts: 3
Registered: 12/4/06
Re: PHP: S3 Signature for URL
Posted: Jan 29, 2009 1:54 AM PST   in response to: pesilatmcasto
  Click to reply to this thread Reply

Thanks for the code. It explained the way signing works clearly enough for me to rewrite it in .NET (C#) (with a bit of googling to find out what some php functions do)

prasadchitale

Posts: 7
Registered: 5/17/09
Re: PHP: S3 Signature for URL
Posted: Jun 18, 2009 11:36 PM PDT   in response to: mtranda
  Click to reply to this thread Reply

Hi!

Have you managed to implement it using C#?

Can you please give me sample code or some documentation about the quesrystring authorisation using C#

Thanks and Regards

Prasad

Colin Rhodes

Posts: 1,265
Registered: 10/10/07
Re: PHP: S3 Signature for URL
Posted: Jun 19, 2009 7:52 AM PDT   in response to: prasadchitale
  Click to reply to this thread Reply

The ThreeSharp library has QSA built in.


Point your RSS reader here for a feed of the latest messages in all forums