如何获取AWS服务器端加密对象 [英] How to get aws sever-side encrypted object

查看:69
本文介绍了如何获取AWS服务器端加密对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将对象存储在S3并为此进行检索

I am trying to store object at S3 and retrieve it for that I am doing following

$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;
}

它工作得很好,我得到的网址是

it works perfectly fine I am getting url like

http://demobucketname.s3.amazonaws.com/ab.png?AWSAccessKeyId=AKIAJUZQHGRTYNOLEUXQ&Expires=1445855704&Signature=3y6eAq1fe5PVASma5DPFmjV7BB3dY%3D

如果不添加

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

将对象放到存储桶中时,现在出现以下错误

while putting object to bucket and now I am getting following error

<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>

现在如何创建在这种情况下也可以使用的签名网址?

now how to create signed url which works in this case too?

推荐答案

使用预先签名的URL上载新对象,检索现有对象或仅检索对象元数据时,必须在客户端应用程序中提供所有加密 headers .(添加了重点)

http://docs.aws.amazon.com/AmazonS3/Latest/dev/ServerSideEncryptionCustomerKeys.html

请注意标题",而不是查询字符串参数.

Note "headers," not query string parameters.

SSE-C本质上不支持在Web浏览器中使用签名的URL……这是有道理的,因为暴露带有嵌入的加密密钥的预签名URL也会暴露加密密钥.

SSE-C essentially doesn't support signed URLs for use in web browsers... which makes sense, since exposing pre-signed URL with the encryption key embedded would also expose the encryption key.

如果您需要在服务器端对用户数据进行加密,并且用户要使用预先签名的URL访问数据,则SSE-C不太可能是正确的选择.

If you need user data encrypted server-side, and for users to access the data with pre-signed URLs, SSE-C isn't likely the correct choice.

这篇关于如何获取AWS服务器端加密对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆