我正在尝试将对象存储在S3并检索它,因为我正在执行以下操作
$key = 'myverykey';
$hash = hash_hmac('sha256',$key,true);
$SSECustomerKey = substr($hash,0,32);
$params = [
'Bucket' => 'somebucketname',
'Key' => 'abc.png',
'Body' => "resource",
'ACL' => 'private',
'SSECustomerAlgorithm' => 'AES256',
'SSECustomerKey' => $SSECustomerKey,
'SSECustomerKeyMD5' => md5($SSECustomerKey, true),
];
s3->putObject($params);
然后我创建了像
这样的签名网址echo el_s3_getTemporaryLink(id, 'mysecretkey', 'cloudfront-config', 'ab.png');
function el_crypto_hmacSHA1($key, $data, $blocksize = 64) {
if (strlen($key) > $blocksize) $key = pack('H*', sha1($key));
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack( 'H*', sha1(
($key ^ $opad) . pack( 'H*', sha1(
($key ^ $ipad) . $data
))
));
return base64_encode($hmac);
}
function el_s3_getTemporaryLink($accessKey, $secretKey, $bucket, $path, $expires = 1) {
$expires = time() + intval(floatval($expires) * 60);
$path = str_replace('%2F', '/', rawurlencode($path = ltrim($path, '/')));
$signpath = '/'. $bucket .'/'. $path;
$signsz = implode("\n", $pieces = array('GET', null, null, $expires, $signpath));
$signature = el_crypto_hmacSHA1($secretKey, $signsz);
$url = sprintf('http://%s.s3.amazonaws.com/%s', $bucket, $path);
$qs = http_build_query($pieces = array(
'AWSAccessKeyId' => $accessKey,
'Expires' => $expires,
'Signature' => $signature,
));
return $url.'?'.$qs;
}
它完全正常我正在获取网址
http://demobucketname.s3.amazonaws.com/ab.png?AWSAccessKeyId=AKIAJUZQHGRTYNOLEUXQ&Expires=1445855704&Signature=3y6eAq1fe5PVASma5DPFmjV7BB3dY%3D
如果我不添加
,我可以访问私人对象'SSECustomerAlgorithm' => 'AES256',
'SSECustomerKey' => $SSECustomerKey,
'SSECustomerKeyMD5' => md5($SSECustomerKey, true),
将对象放入存储桶时,现在我遇到了以下错误
<Error>
<Code>InvalidRequest</Code>
<Message>
The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object.
</Message>
<RequestId>E19B53C0EE2A6E7C</RequestId>
<HostId>
WOwzj29NBh49uE5Lmtut96PFY8pf3UD8bBWGLXdAFHryNT94WD7qJbqMbu7fKCfROKEIWKwPPX4=
</HostId>
</Error>
现在如何创建在这种情况下有效的签名网址?
答案 0 :(得分:3)
使用预签名网址上传新对象,检索现有对象或仅检索对象元数据时,必须在客户端应用程序中提供所有加密标题。 (重点补充)
http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
注意&#34;标题,&#34;不查询字符串参数。
SSE-C基本上不支持在Web浏览器中使用的签名URL ...这是有道理的,因为使用嵌入的加密密钥公开预签名URL也会暴露加密密钥。
如果您需要在服务器端加密用户数据,并且要让用户使用预先签名的URL访问数据,那么SSE-C可能不是正确的选择。