It is a bit strange to me this isn't a commonly discussed topic yet but I am working with an AWS S3 storage server trying to implement server-side encryption using the option of a client provided key (SSE-C).
More Information Here: http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
I have the encryption method working great when attempting to use the AWS Key Management Service (KMS). The issue I personally have is I want to hold the keys, thus leading me to want the SSE-C method.
Documentation for PHP (for whatever reason) is scarce under this subject but I have managed to get it working using the seemingly most recent composer build of version3 for S3.
My connection code and put object to the system is as follows. Files are properly uploaded to the system. Code is as follows:
//connect is successful
$client = Aws\S3\S3Client::factory([
'version' => "2006-03-01",
'region' => "us-west-1",
'credentials' => [
'key' => "mykey",
'secret' => "mysecret"
]
]);
//upload is successful
$somerandom32bitkey="48wk86271sDb23pY23zT5rZJ7q55R7eE";
$result = $client->putObject([
'Bucket' => 'mybucketname',
'Key' => 'myfilename',
'Body' => 'some body of the file',
'SSECustomerAlgorithm' => 'AES256',
'SSECustomerKey' => $somerandom32bitkey,
'SSECustomerKeyMD5' => md5($somerandom32bitkey,true),
]);
My issue arises when attempting to get a pre-signed url. I cannot seem to find any documentation on how to actually do this part which is pretty important. The code is as follows:
$somerandom32bitkey="48wk86271sDb23pY23zT5rZJ7q55R7eE";
$cmd = $client->getCommand('GetObject', array(
'Bucket' => 'mybucketname',
'Key' => 'myfilename',
'SSECustomerAlgorithm' => 'AES256',
'SSECustomerKey' => $somerandom32bitkey,
'SSECustomerKeyMD5' => md5($somerandom32bitkey,true),
));
$request = $client->createPresignedRequest($cmd, '+10 minutes');
$presignedUrl = (string) $request->getUri();
The link generated looks like this:
The result response via AWS is:
<Error>
<Code>InvalidArgument</Code>
<Message>
Requests specifying Server Side Encryption with Customer provided keys must provide an appropriate secret key.
</Message>
<ArgumentName>x-amz-server-side-encryption</ArgumentName>
<ArgumentValue>null</ArgumentValue>
<RequestId>933237342E36A1D1</RequestId>
<HostId>
3XmQM+IEGdZUZ5GUnSpTpatksKIN2zb3pCiu8D7Btm09nLxKkfEAkfY8a8T8kcB3lW1p38ic3ZE=
</HostId>
</Error>
The interesting part is it is looking for a parameter of: 'ServerSideEncryption' => 'AES256' but this is only a parameter required when using the AWS managed key system (SSE-KMS) http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html
Any ideas here?