Amazon S3客户提供的PHP SDK加密

时间:2015-04-12 07:42:36

标签: php amazon-web-services amazon-s3

我正在尝试使用客户提供的加密密钥将对象上传到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))。

提前致谢

1 个答案:

答案 0 :(得分:2)

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

  

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

     

使用此标头为Amazon S3提供256位base64编码的加密密钥,用于加密或解密数据。

     

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

     

根据RFC 1321,使用此标头提供加密密钥的base64编码的128位MD5摘要.Amazon S3使用此标头进行消息完整性检查,以确保加密密钥的传输没有错误。

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

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

当然,您可能希望在变量中使用32字节的密钥字符串,而不是在代码中将相同的文字字符串复制两次。第二个论点" true"到md5() specifies要返回二进制md5哈希,如SDK所预期的那样,而不是默认返回的十六进制编码变体。

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