簡體   English   中英

如何使用帶有 ksm 加密的 aws s3 createPresignedPost

[英]How to use aws s3 createPresignedPost with ksm encryption

我已經找到了與 Java 一起執行此操作的 aws 文檔,以及一些針對 javascript 開發人員的零散參考,但如果沒有收到 aws 拒絕的訪問權限,我將無法完成此操作。 我嘗試了很多不同的變體。

更糟糕的是,我的開發環境是一個專有框架,可以在后台處理很多角色和憑證,但我已經能夠確定 ksm 策略是症結所在,但我還沒有找到解決方案.

我試過將參數傳遞給簽名過程:

const params = {
    Bucket: targetBucket,
    ServerSideEncryption: 'aws:kms',
    SSEKMSKeyId: keyId,
    Conditions: [{ acl: 'private' }, { key: filepath } ]
};
return new Promise((res, rej) => {
    clientS3.createPresignedPost(params, (err, data) => {
        if (err) {
            console.log(err.message);
            rej(err);
        } else {
            console.log(data);
            res({ data, filepath, encryption, bucket });
        }
    });
});

那沒有用。 拒絕訪問。 (是的,我將這些值包含在表單數據中,以確保正確簽署請求。)

我還嘗試通過以下方式將標頭添加到發布請求本身:

return axios
  .post(response.data.url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      'x-amz-server-side-encryption-aws-kms-key-id': response.encryption,
      'x-amz-server-side-encryption-context': bucketArn
    },
    ....

拒絕訪問。 我試過混合和匹配方法。 我可以通過破壞簽名使事情變得更糟,但我無法獲取加密文件或找到文檔來完成此操作。

更新:根據 jarmod,我已驗證訪問角色具有加密和生成數據密鑰的 KMS 權限; 並且我已經驗證刪除存儲桶上的加密策略允許上傳沒有問題。

所描述的政策是:

{
        "Effect": "Deny",
        "Principal": "*",
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::[[ bucket name ]]/*",
        "Condition": {
            "StringNotLikeIfExists": {
                "s3:x-amz-server-side-encryption-aws-kms-key-id": "[[ kms arn ]]"
            }
        }
    }

更新

添加 header x-amz-server-side-encryption: aws:kms后,我沒有得到更好的結果。 完整的請求標頭是:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 307546
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary4B20k5OmUGzGhYoV
Host: s3.us-west-2.amazonaws.com
Origin: http://localhost:8888
Referer: http://localhost:8888/ 
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
x-amz-server-side-encryption: aws:kms
x-amz-server-side-encryption-aws-kms-key-id: [[ full arn of kms key ]] 
x-amz-server-side-encryption-context: arn:aws:s3:::[[ bucket name ]]/*

響應標頭是:

Request URL: https://s3.us-west-2.amazonaws.com/[[ bucket name ]] 
Request Method: POST
Status Code: 403 Forbidden
Remote Address: 52.92.145.80:443
Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Origin: http://localhost:8888
Connection: close
Content-Type: application/xml
Date: Mon, 05 Dec 2022 02:07:11 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2: [[ ugly amz string ]]
x-amz-request-id: [[ shorter amz string ]] 

響應負載是:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message>. 
<RequestId>[[ same as header request id ]]</RequestId>. 
<HostId>[[ same as long amz id in headers ]] </HostId></Error>

最后,表單數據的有效載荷是:

acl: private
key: [[ filename ]]
bucket: [[ bucket ]]
X-Amz-Algorithm: AWS4-HMAC-SHA256
X-Amz-Credential: [[credential string ]]
X-Amz-Date: 20221205T020711Z
X-Amz-Security-Token: [[ token ]]
Policy: [[ policy string ]]
X-Amz-Signature: [[ signature string ]]
file: (binary)

下面是使用客戶管理的 KMS 密鑰加密的 S3 預簽名 URL 上傳的工作示例。 我使用 JS SDK v3 @aws-sdk/s3-request-presigner package 進行簽名和 Node18 的本地獲取。

我使用兩個存儲桶策略場景對其進行了測試:(a) 您的存儲桶策略逐字記錄 (b) 此AWS 知識中心問答中的策略。 根據以下標頭的兩個策略,上傳成功。 正如預期的那樣,如果刪除了所需的標頭,它會失敗並403響應。

const body = "Uploaded with a pre-signed URL and Customer-managed KMS key!";
const keyId = "arn:aws:kms:us-east-1:123456789012:key/231389a0-...";

const command = new PutObjectCommand({
  Bucket: "my-bucket-123456789012-us-east-1",
  Key: `myFile.txt`,
  ServerSideEncryption: "aws:kms",
  SSEKMSKeyId: keyId, 
  Body: body,
});

const url = await getSignedUrl(client, command, { expiresIn: 3600 });

const res = await fetch(url, {
  method: "PUT",
  headers: {
    "x-amz-server-side-encryption": "aws:kms",
    "x-amz-server-side-encryption-aws-kms-key-id": keyId,
  },
  body,
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM