可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am working on AWS EC2 Ubuntu Machine and trying to fetch image from AWS S3 but following error has been shown to me every time.
<Error> <Code>InvalidArgument</Code> <Message> Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4. </Message> <ArgumentName>Authorization</ArgumentName> <ArgumentValue>null</ArgumentValue> <RequestId>7C8B4BF1CE2FDC9E</RequestId> <HostId> /L5kjuOET4XFgGter2eFHX+aRSvVm/7VVmIBqQE/oMLeQZ1ditSMZuHPOlsMaKi8hYRnGilTqZY= </HostId> </Error>
Here is my bucket policy
{ "Version": "2012-10-17", "Id": "Policy1441213815928", "Statement": [ { "Sid": "Stmt1441213813464", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::mytest.sample/*" } ] }

Here is the code
require 'aws-autoloader.php'; $credentials = new Aws\Credentials\Credentials('key', 'key'); $bucketName = "mytest.sample"; $s3 = new Aws\S3\S3Client([ 'signature' => 'v4', 'version' => 'latest', 'region' => 'ap-southeast-1', 'credentials' => $credentials, 'http' => [ 'verify' => '/home/ubuntu/cacert.pem' ], 'Statement' => [ 'Action ' => "*", ], ]); $result = $s3->getObject(array( 'Bucket' => $bucketName, 'Key' => 'about_us.jpg', ));
Html
<img src="<?php echo $result['@metadata']['effectiveUri']; ?>" />
Edit for Michael - sqlbot : here I am using default KMS.
try { $result = $this->Amazon->S3->putObject(array( 'Bucket' => 'mytest.sample', 'ACL' => 'authenticated-read', 'Key' => $newfilename, 'ServerSideEncryption' => 'aws:kms', 'SourceFile' => $filepath, 'ContentType' => mime_content_type($filepath), 'debug' => [ 'logfn' => function ($msg) { echo $msg . "\n"; }, 'stream_size' => 0, 'scrub_auth' => true, 'http' => true, ], )); } catch (S3Exception $e) { echo $e->getMessage() . "\n"; }
let me know if you need more.
回答1:
I have also face this issue with aws:kms
encyrption key, I suggest that if you wanted to use kms
key then you have to create your kms key
in IAM section of AWS Console
. I love to recommended AES256
server side encryption, here S3 automatically Encrypted your data while putting and decryption while getting object. Please go through below link: S3 Server Side encryption with AES256
My Solution is change this line 'ServerSideEncryption' => 'aws:kms' with 'ServerSideEncryption' => 'AES256'
try { $result = $this->Amazon->S3->putObject(array( 'Bucket' => 'mytest.sample', 'ACL' => 'authenticated-read', 'Key' => $newfilename, 'ServerSideEncryption' => 'AES256', 'SourceFile' => $filepath, 'ContentType' => mime_content_type($filepath), 'debug' => [ 'logfn' => function ($msg) { echo $msg . "\n"; }, 'stream_size' => 0, 'scrub_auth' => true, 'http' => true, ], )); } catch (S3Exception $e) { echo $e->getMessage() . "\n"; }
Please also update your bucket policy with below json, it will prevent you to upload object with out AES256
encryption
{ "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::yourbucketname/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "AES256" } } }
回答2:
PHP sdk v2
- the Credentials package is
Aws\Common\Credentials
- to create an
S3Client
you need a factory
Try something like this
use Aws\S3\S3Client; use Aws\Common\Credentials\Credentials; $credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY'); // Instantiate the S3 client with your AWS credentials $s3Client = S3Client::factory(array( 'signature' => 'v4', 'region' => 'ap-southeast-1', 'credentials' => $credentials, ..... ]); )
If that does not work you might try to declare explicitly a SignatureV4
object
use Aws\S3\S3Client; use Aws\Common\Credentials\Credentials; use Aws\Common\Signature\SignatureV4; $credentials = new Credentials('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY'); // Instantiate the S3 client with your AWS credentials $s3Client = S3Client::factory(array( 'signature' => new SignatureV4(), 'region' => 'ap-southeast-1', 'credentials' => $credentials, ..... ]); )
In case you upgrade to sdk v3
- You need to have
signature_version
(instead of signature
) as parameter when you declare your s3 client Statement
does not appear to be a valid parameter (http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#signature-version) - if issue you can turn on
debug
param to get more output
This would look like this
$s3 = new Aws\S3\S3Client([ 'signature_version' => 'v4', 'version' => 'latest', 'region' => 'ap-southeast-1', 'credentials' => $credentials, 'http' => [ 'verify' => '/home/ubuntu/cacert.pem' ], 'debug' => true ]);
see here for the full list of available parameter