【问题标题】:Amazon S3 Client Side Encryption JavascriptAmazon S3 客户端加密 Javascript
【发布时间】:2015-12-04 00:17:39
【问题描述】:

尝试让 Amazon S3 客户端加密与 Javascript 一起使用。

为存储桶中的特定 S3 对象建立 SSE 是 可选,并且可以很容易地在单个对象级别建立。 还可以设置“一揽子”策略,要求将所有数据发送到 S3 要加密的存储桶。此类策略的示例如下:

{
  "Version":"2013-05-17",
  "Id":"PutObjPolicy",
  "Statement":[{
     "Sid":"DenyUnEncryptedObjectUploads",
     "Effect":"Deny",
     "Principal":{
      "AWS":"*"
     },
     "Action":"s3:PutObject",
     "Resource":"arn:aws:s3:::SensitiveBucket/*",
     "Condition":{
      "StringNotEquals":{
        "s3:x-amz-server-side-encryption":"AES256"
      }
     }
   }
  ]
}

要成功地将任何数据放入此 S3 存储桶,请求将 需要包含“x-amz-server-side-encryption”标头。

因为它是客户端,所以我得到了这个 JSON 策略设置:

{
  "expiration": "2020-01-01T00:00:00Z",
  "conditions": [
    {"bucket": "angular-file-upload"},
    ["starts-with", "$key", ""],
    {"acl": "private"},
 { "x-amz-server-side-encryption": "AES256"},
 {"x-amz-server-side​-encryption​-customer-key": "ABC1234835784375349754857893"},
 {"x-amz-server-side​-encryption​-customer-key-MD5": "d0259989a64a9234457dbc51d5202c24"},
   ["starts-with", "$Content-Type", ""],
    ["starts-with", "$filename", ""],
    ["content-length-range", 0, 524288000]
  ]
}

将文件 CORs-ways 发送到 S3 (POST),并在上传期间另外发送 x-amz-server-side-encryption 标头。

尝试了两种 json 策略,但是它们都抛出了相同的结果。

响应如下:

    <Error><Code>AccessDenied</Code>
<Message>Invalid according to Policy: Extra input fields: x-amz-server-side​-encryption​-customer-key</Message><RequestId>...</RequestId><HostId>...</HostId></Error>

有人知道这里发生了什么吗? 最近我什至好奇是否有可能使用 JS 和 Cors 加密客户端。

干杯。

【问题讨论】:

  • 不发送标头。

标签: javascript json amazon-web-services encryption amazon-s3


【解决方案1】:

通过在创建和 base64 编码的策略以及在 AJAX 请求中发送的表单数据中包含 x-amz-server-side-encryption,我能够摆脱这个警告。

政策:

            var s3Policy = {
                "expiration": formatted,
                "conditions": [
                    { "bucket": "MYBUCKET" },
                    { "acl": config.acl },
                    { "x-amz-server-side-encryption": "AES256" },
                    [ "eq", "$key", path],
                    [ "eq", "$Content-Type", mimetype ],
                    [ "content-length-range", 0, maxSize ],
                ]
            };

表单发布数据:

            data.params = {
                key: path,
                AWSAccessKeyId: key,
                acl: acl,
                Policy: base64Policy,
                Signature: signature,
                "Content-Type": mimetype,
                "x-amz-server-side-encryption": "AES256",
            },

为了完整起见,我还有以下 CORS 配置:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
        <AllowedHeader>Content-Type</AllowedHeader>
        <AllowedHeader>x-amz-acl</AllowedHeader>
        <AllowedHeader>origin</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

和存储桶策略(强制加密):

{
    "Version": "2012-10-17",
    "Id": "Policy1447114958606",
    "Statement": [
        {
            "Sid": "Stmt1447114951553",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::MYBUCKET/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "AES256"
                }
            }
        }
    ]
}

我将文件实际发布到 s3 的代码如下所示,但这取决于您选择使用的库和包装器:

    // Build the form data (this is what we will eventually post)
    var fd = new FormData();
    if (data.params)
    {
        for (var prop in data.params) {
            if (data.params.hasOwnProperty(prop)) {
                fd.append(prop,data.params[prop]);
            }
        }
    }
    fd.append('file', file);

    // Post data
    var deferred = $q.defer();
    var req = $.ajax({
        type: 'POST',
        url: data.url,
        data: fd,
        cache: false,
        contentType: false,
        processData: false,
        success: function(response, textStatus, jqXHR) { deferred.resolve(response); },
        error: function(jqXHR, textStatus, errorThrown) { deferred.reject(errorThrown || "Upload failed, try again"); },
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) myXhr.upload.addEventListener('progress', function (progress) { deferred.notify(progress); }, false);
            return myXhr;
        }
    });
    var promise = deferred.promise;
    promise.cancel = function()
    {
        req.abort();
        deferred.reject("Cancelled");
    };
    return promise;

【讨论】:

  • 我刚刚注意到您希望使用自定义密钥进行加密,但不确定我的建议在这种情况下是否真的有帮助。
猜你喜欢
  • 2021-01-02
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多