1

I am trying to download file from amazon s3 but getting following error

<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>

Following code we use

<?php
$accessKey = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
$secretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxx';

$datestamp = new DateTime( "now" );
$longdate = $datestamp->format( "Ymd\\THisZ");
$shortdate = $datestamp->format( "Ymd" );
$date = date('Ymd',time());
$timestamp = date('Ymd',time()).'T'.date('His',time()).'Z';
$shortdate =  date('Ymd',time());
$region = 'ap-south-1';
$service = 's3';
$request    = 'aws4_request';
$ksecret = 'AWS4' . $secretKey;
$kdate = hash_hmac( 'sha256', $shortdate, $ksecret );
$kregion = hash_hmac( 'sha256', $region, $kdate );
$kservice = hash_hmac( 'sha256', $service, $kregion );
$ksigning = hash_hmac( 'sha256', $request, $kservice );
$canonicalRequest = "GET\n";
$canonicalRequest .= "/\n";
$canonicalRequest .= "\n";
$canonicalRequest .= "host:bucketname.s3.amazonaws.com\n";
$canonicalRequest .= "x-amz-date:". $timestamp ."\n";
$canonicalRequest .= "\n";
$canonicalRequest .= "host;x-amz-date\n";
$canonicalRequest .= hash( 'sha256', '{}' );
$canonicalRequest = hash( 'sha256', $canonicalRequest );
$stringToSign = "AWS4-HMAC-SHA256\n";
$stringToSign .= $longdate . "\n";
$stringToSign .= $shortdate . "/". $region ."/". $service ."/". $request ."\n";
$stringToSign .= $canonicalRequest;
echo $stringToSign;
echo "<br>";
echo $ksigning;
echo "<br>";
$signature = hash_hmac( 'sha256', $stringToSign, base64_encode($ksigning) );
$params = [
    'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
    'X-Amz-Credential' => $accessKey . '/'. $shortdate .'/'. $region .'/'. $service .'/' . $request,
    'X-Amz-Date'    => $timestamp,
    'X-Amz-Expires' => 86400,
    'X-Amz-SignedHeaders'   => 'host;x-amz-date',
    'X-Amz-Signature'   => trim($signature)
];
$url = 'https://bucketname.s3.amazonaws.com/1.jpg';
$count = 0;
foreach($params AS $key => $value)
{
    $count++;
    $url .= ($count == 1 ? '?' : '&') . $key .= '=' . $value;
}
echo $url . "
";
1

I try following way to solve this problem

<?php
require('aws.phar');

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

$config = array(
    'version' => '2006-03-01',
    'credentials' => [
        'key'    => 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
        'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
    ],
    'region'  => 'ap-south-1',  // your region get from amazon s3
);

$s3v2 = S3Client::factory($config);
$cmd = $s3v2->getCommand('GetObject', [
    'Bucket' => 'bucket_name',
    'Key'    => '1.jpg'  // file name 
]);

$request = $s3v2->createPresignedRequest($cmd, '+20 minutes');

// Get the actual presigned-url
$presignedUrl = (string)$request->getUri();
echo $presignedUrl;
?>

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.