Amazon S3 客户使用 PHP SDK 提供加密

Amazon S3 Customer Provided Encryption with PHP SDK

我正在尝试使用客户提供的加密密钥将对象上传到 S3。 http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html

我的代码如下:

$this->s3->putObject(array(
  'Bucket' => $this->bucket,
  'Key' => "$filename",
  'Body' => $resource,
  'ACL' => 'private',
  'SSECustomerAlgorithm' => 'AES256',
  'SSECustomerKey' => base64_encode('48wk86271sDb23pY23zT5rZJ7q55R7eE'),
  'SSECustomerKeyMD5'=> base64_encode(md5('48wk86271sDb23pY23zT5rZJ7q55R7eE'))
));

我得到的错误是:

AWS Error Message: The calculated MD5 hash of the key did not match the hash that was provided

我做错了什么?我的密钥 48wk86271sDb23pY23zT5rZJ7q55R7eE 是 256 位。我也试过使用 base64_encode(md5(key, true)).

REST API documentation 指定客户密钥和客户密钥 MD5 均以 base-64 编码发送...

x-amz-server-side​-encryption​-customer-key

Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data.

x-amz-server-side​-encryption​-customer-key-MD5

Use this header to provide the base64-encoded 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a message integrity check to ensure the encryption key was transmitted without error.

...但是,PHP SDK 会为您处理这两个编码步骤,因此应在不进行任何编码的情况下传递参数。

'SSECustomerAlgorithm' => 'AES256',
'SSECustomerKey'       => 'key_=_string_of_exactly_32_bytes',
'SSECustomerKeyMD5'    => md5('key_=_string_of_exactly_32_bytes',true),

当然,您可能希望将 32 字节密钥字符串放在一个变量中,而不是在代码中复制粘贴相同的文字字符串两次。 md5() specifies 的第二个参数“true”表示将按照 SDK 的预期返回二进制 md5 哈希,而不是默认返回的十六进制编码变体。

请记住,使用客户提供的加密密钥时,如果您丢失了密钥,就会丢失数据。 S3 不存储密钥,没有密钥,无法获取存储的对象。