

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Amazon S3 受管金鑰 (SSE-S3) 進行伺服器端加密
<a name="UsingServerSideEncryption"></a>

**重要**  
Amazon S3 現在將伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 套用為 Amazon S3 中每個儲存貯體的基本加密層級。從 2023 年 1 月 5 日起，所有上傳到 Amazon S3 的新物件都會自動加密，無需額外費用，也不會影響效能。S3 儲存貯體預設加密組態和新物件上傳的自動加密狀態可在 CloudTrail 日誌、S3 庫存、S3 Storage Lens、Amazon S3 主控台，以及 AWS CLI 和 AWS SDKs 中的其他 Amazon S3 API 回應標頭中使用。如需詳細資訊，請參閱[預設加密常見問答集](https://docs.aws.amazon.com/AmazonS3/latest/userguide/default-encryption-faq.html)。

所有上傳到 Amazon S3 儲存貯體的新物件均會使用伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 進行加密。

伺服器端加密保護靜態資料。Amazon S3 會使用不重複的金鑰加密每個物件。它使用定期輪換的金鑰自行加密金鑰，提供額外的防護。Amazon S3 伺服器端加密使用 256 位元 Galois/計數器模式中的進階加密標準 (AES-GCM) 來加密所有上傳的物件。

將伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 搭配使用不需另外付費。不過，請求設定預設加密功能會產生標準 Amazon S3 請求費用。如需定價的資訊，請參閱 [Amazon S3 定價](https://aws.amazon.com/s3/pricing/)。

若您希望上傳的資料僅使用 Amazon S3 受管金鑰加密，您可以使用下列儲存貯體政策。例如，除非要求包含 `x-amz-server-side-encryption`標頭以要求伺服器端加密，否則以下儲存貯體政策會拒絕上傳物件的許可權限：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "PutObjectPolicy",
  "Statement": [
    {
      "Sid": "DenyObjectsThatAreNotSSES3",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    }
   ]
}
```

------

**注意**  
伺服器端加密只會加密物件資料，非物件中繼資料。

## 伺服器端加密的 API 支援
<a name="APISupportforServer-SideEncryption"></a>

根據預設，所有 Amazon S3 儲存貯體都設定了加密，所有上傳到 S3 儲存貯體的新物件都會在靜態時自動加密。伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 是 Amazon S3 中每個儲存貯體的預設加密組態。若要使用不同類型的加密，您可以指定 S3 `PUT` 請求中要使用的伺服器端加密類型，也可以在目的地儲存貯體中更新預設加密組態。

如果您想要在`PUT`請求中指定不同的加密類型，您可以使用伺服器端加密搭配 AWS Key Management Service (AWS KMS) 金鑰 (SSE-KMS)、雙層伺服器端加密搭配 AWS KMS 金鑰 (DSSE-KMS)，或伺服器端加密搭配客戶提供的金鑰 (SSE-C)。若您想在目的地儲存貯體中設定不同的預設加密組態，您可以使用 SSE-KMS 或 DSSE-KMS。

如需變更一般用途儲存貯體之預設加密組態的詳細資訊，請參閱 [設定預設加密](default-bucket-encryption.md)。

當您將儲存貯體的預設加密組態變更為 SSE-KMS 時，並不會變更儲存貯體中現有 Amazon S3 物件的加密類型。若要在將預設加密組態更新為 SSE-KMS 之後變更既有物件的加密類型，您可以使用 Amazon S3 Batch Operations。您為 S3 Batch Operations 提供物件清單，而批次操作會呼叫個別 API 操作。您可以使用 [複製物件](batch-ops-copy-object.md) 動作來複製現有物件，該動作會將它們寫回與 SSE-KMS 加密物件相同的儲存貯體。單一批次操作任務可在數十億個物件上執行指定的操作。如需詳細資訊，請參閱 [使用 Batch Operations 大量執行物件操作](batch-ops.md) 和 *AWS 儲存部落格*文章[如何使用 S3 庫存清單、Amazon Athena 和 S3 Batch Operations 來追溯加密 Amazon S3 中的現有物件](https://aws.amazon.com/blogs/security/how-to-retroactively-encrypt-existing-objects-in-amazon-s3-using-s3-inventory-amazon-athena-and-s3-batch-operations/)。

若要使用物件建立 REST API，用以設定伺服器端加密，請務必提供 `x-amz-server-side-encryption` 要求標頭。如需 REST APIs 的相關資訊，請參閱[使用 REST API](specifying-s3-encryption.md#SSEUsingRESTAPI)。

下列 Amazon S3 API 支援此標頭。
+ **PUT 操作** — 使用 `PUT` API 上傳資料時，請指定要求標頭。如需詳細資訊，請參閱 [PUT 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)。
+ **啟動分段上傳** — 使用分段上傳 API 操作上傳大型物件時，您可於起始要求時，指定這些標頭。如需詳細資訊，請參閱[啟動分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)。
+ **COPY 操作** — 當您複製物件時，要有來源物件與目標物件。如需詳細資訊，請參閱 [PUT 物件 - 複製](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)。

**注意**  
使用 `POST` 操作上傳物件時，請您提供與表單欄位中相同的資訊，而非提供要求標頭。如需詳細資訊，請參閱 [POST 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)。

 AWS SDKs 也提供包裝函式 APIs，您可以用來請求伺服器端加密。您也可以使用 AWS 管理主控台 上傳物件並請求伺服器端加密。

如需更多一般資訊，請參閱《AWS Key Management Service 開發人員指南》**中的 [AWS KMS 概念](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html)。

**Topics**
+ [伺服器端加密的 API 支援](#APISupportforServer-SideEncryption)
+ [使用 Amazon S3 受管金鑰 (SSE-S3) 指定伺服器端加密](specifying-s3-encryption.md)

# 使用 Amazon S3 受管金鑰 (SSE-S3) 指定伺服器端加密
<a name="specifying-s3-encryption"></a>

根據預設，所有 Amazon S3 儲存貯體都設定了加密，所有上傳到 S3 儲存貯體的新物件都會在靜態時自動加密。伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 是 Amazon S3 中每個儲存貯體的預設加密組態。若要使用不同類型的加密，您可以指定 S3 `PUT` 請求中要使用的伺服器端加密類型，也可以在目的地儲存貯體中更新預設加密組態。

如果您想要在`PUT`請求中指定不同的加密類型，您可以使用伺服器端加密搭配 AWS Key Management Service (AWS KMS) 金鑰 (SSE-KMS)、雙層伺服器端加密搭配 AWS KMS 金鑰 (DSSE-KMS)，或伺服器端加密搭配客戶提供的金鑰 (SSE-C)。若您想在目的地儲存貯體中設定不同的預設加密組態，您可以使用 SSE-KMS 或 DSSE-KMS。

如需變更一般用途儲存貯體之預設加密組態的詳細資訊，請參閱 [設定預設加密](default-bucket-encryption.md)。

當您將儲存貯體的預設加密組態變更為 SSE-KMS 時，並不會變更儲存貯體中現有 Amazon S3 物件的加密類型。若要在將預設加密組態更新為 SSE-KMS 之後變更既有物件的加密類型，您可以使用 Amazon S3 Batch Operations。您為 S3 Batch Operations 提供物件清單，而批次操作會呼叫個別 API 操作。您可以使用 [複製物件](batch-ops-copy-object.md) 動作來複製現有物件，該動作會將它們寫回與 SSE-KMS 加密物件相同的儲存貯體。單一批次操作任務可在數十億個物件上執行指定的操作。如需詳細資訊，請參閱 [使用 Batch Operations 大量執行物件操作](batch-ops.md) 和 *AWS 儲存部落格*文章[如何使用 S3 庫存清單、Amazon Athena 和 S3 Batch Operations 來追溯加密 Amazon S3 中的現有物件](https://aws.amazon.com/blogs/security/how-to-retroactively-encrypt-existing-objects-in-amazon-s3-using-s3-inventory-amazon-athena-and-s3-batch-operations/)。

您可以使用 SSE-S33 AWS CLI。 APIs AWS SDKs AWS Command Line Interface 如需詳細資訊，請參閱[對 Amazon S3 儲存貯體設定預設伺服器端加密行為](bucket-encryption.md)。

## 使用 S3 主控台
<a name="add-object-encryption-s3"></a>

本主題說明如何使用 AWS 管理主控台設定或變更物件所使用的加密類型。當您使用主控台複製物件時，Amazon S3 會依原樣複製物件。這表示，若來源物件已加密，則目標物件也會加密。您可以使用主控台來新增或變更物件的加密。

**注意**  
如果您的物件小於 5 GB，您可以變更物件的加密。如果您的物件大於 5 GB，您必須使用 [AWS CLI](mpu-upload-object.md#UsingCLImpUpload) 或 [AWS SDK](CopyingObjectsMPUapi.md) 來變更物件的加密。
如需變更物件加密所需的其他許可清單，請參閱[Amazon S3 API 操作所需的許可](using-with-s3-policy-actions.md)。如需授予此許可的範例政策，請參閱[Amazon S3 的身分型政策範例](example-policies-s3.md)。
如果您變更物件的加密，則會建立新物件來取代舊物件。如果啟用 S3 版本控制，則系統會建立物件的新版本，且現有物件會變成較舊的版本。變更屬性的角色也會成為新物件 (或物件版本) 的擁有者。

**變更物件的加密**

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/) 開啟 Amazon S3 主控台。

1. 在導覽窗格中，選擇**儲存貯體**，然後選擇**一般用途儲存貯體**索引標籤。導覽至包含您要變更之物件的 Amazon S3 儲存貯體或資料夾。

1. 選取您要變更之物件的核取方塊。

1. 從**動作**功能表上顯示的選項清單中，選擇**編輯伺服器端加密**。

1. 捲動至**伺服器端加密**區段。

1. 在**加密設定**底下，選擇**使用預設加密的儲存貯體設定**或**覆寫預設加密的儲存貯體設定**。

1. 若您選擇**覆寫預設加密的儲存貯體設定**，請設定下列加密設定。

   1. 在**加密類型**下，選擇**使用 Amazon S3 受管金鑰的伺服器端加密 (SSE-S3)**。SSE-S3 使用目前最強大的其中一種區塊加密法，也就是 256 位元進階加密標準 (AES-256)，來加密每個物件。如需詳細資訊，請參閱[使用 Amazon S3 受管金鑰 (SSE-S3) 進行伺服器端加密](UsingServerSideEncryption.md)。

1. 在**其他複製設定**下，選擇**複製來源設定**、**不要指定設定**或**指定設定**。**複製來源設定**是預設選項。如果您只想複製物件但不想包含來源設定屬性，請選擇**不要指定設定**。選擇**指定設定**以指定儲存類別、ACL、物件標籤、中繼資料、伺服器端加密和額外檢查總和的設定。

1. 選擇 **Save changes** (儲存變更)。

**注意**  
此動作會將加密套用至所有指定的物件。加密資料夾時，請等待儲存作業完成，然後再將新物件新增至資料夾。

## 使用 REST API
<a name="SSEUsingRESTAPI"></a>

建立物件時 (也就是當您上傳新的物件或複製現有物件時)，可以指定是否在請求中新增 `x-amz-server-side-encryption` 標頭，讓 Amazon S3 以 Amazon S3 受管金鑰 (SSE-S3) 加密您的資料。將標頭值設為 Amazon S3 支援的加密演算法 `AES256`。Amazon S3 會傳回回應標頭 `x-amz-server-side-encryption`，確認已使用 SSE-S3 存放物件。

下列 REST 上傳 API 操作，接受 `x-amz-server-side-encryption` 要求標頭。
+ [PUT 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT 物件 - 複製](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [啟動分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)

使用分段上傳 API 操作上傳大型物件時，可以對啟動分段上傳要求新增 `x-amz-server-side-encryption` 標頭，指定伺服器端加密。複製現有物件時，除非明確地要求伺服器端加密，否則無論來源物件是否經過加密，都不會加密目標物件。

使用 SSE-S3 存放物件時，下列 REST API 操作的回應標頭會傳回 `x-amz-server-side-encryption` 標頭。
+ [PUT 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html)
+ [PUT 物件 - 複製](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html)
+ [POST 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html)
+ [啟動分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadInitiate.html)
+ [上傳片段](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPart.html)
+ [上傳片段 - 複製](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html)
+ [完成分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html)
+ [Get 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html)
+ [Head 物件](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectHEAD.html)

**注意**  
如果物件使用 SSE-S3，請勿為 `GET` 請求與 `HEAD` 請求傳送加密請求標頭，否則您會收到 HTTP 狀態碼 400 (錯誤的請求) 錯誤。

## 使用 AWS SDKs
<a name="s3-using-sdks"></a>

使用 AWS SDKs時，您可以請求 Amazon S3 搭配 Amazon S3 受管加密金鑰 (SSE-S3) 使用伺服器端加密。本節提供以多種語言使用 AWS SDKs的範例。如需其他 SDK 的資訊，請前往[範例程式碼與程式庫](https://aws.amazon.com/code)。

------
#### [ Java ]

當您使用 適用於 Java 的 AWS SDK 上傳物件時，您可以使用 SSE-S3 來加密物件。若要求伺服器端加密，可使用 `ObjectMetadata`，`PutObjectRequest`的屬性，設定 `x-amz-server-side-encryption` 要求標頭。當您呼叫 `AmazonS3Client` 的，`putObject()` 方法時，Amazon S3 會加密和儲存資料。

使用分段上傳 API 操作時，您也可以要求 SSE-S3 加密。
+ 使用高階分段上傳 API 操作，您可以使用 `TransferManager` 方法，應用於上傳伺服器端物件加密。您可使用任一接受 `ObjectMetadata` 為參數的上傳方法。如需詳細資訊，請參閱[使用分段上傳來上傳物件](mpu-upload-object.md)。
+ 使用低階分段上傳 API 操作，可以在啟動分段上傳時，指定伺服器端加密。呼叫 `ObjectMetadata` 的方法，新增 `InitiateMultipartUploadRequest.setObjectMetadata()` 屬性。如需詳細資訊，請參閱[使用 AWS SDKs（低階 API)](mpu-upload-object.md#mpu-upload-low-level)。

您無法直接更改物件的加密狀態 (加密未加密的物件或解密加密的物件)。要更改物件的加密狀態，請複製該物件，指定所需複本的加密狀態，然後刪除原始物件。只有在您明確請求伺服器端加密時，Amazon S3 才會加密複製的物件。使用 `ObjectMetadata` 屬性，在 `CopyObjectRequest` 中透過 API 指定伺服器端加密，要求進行物件複本加密。

**Example 範例**  
下列範例示範如何使用 適用於 Java 的 AWS SDK設定伺服器端加密。說明如何執行以下任務：  
+ 使用 SSE-S3 上傳新物件。
+ 透過製作物件複本，更改物件的加密狀態 (在此範例中，加密先前未加密過的物件)。
+ 確認物件加密狀態。
如需伺服器端加密的詳細資訊，請參閱「[使用 REST API](#SSEUsingRESTAPI)」。如需建立和測試工作範例的說明，請參閱《 適用於 Java 的 AWS SDK 開發人員指南》中的[入門](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/getting-started.html)。  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.internal.SSEResultBase;
import com.amazonaws.services.s3.model.*;

import java.io.ByteArrayInputStream;

public class SpecifyServerSideEncryption {

    public static void main(String[] args) {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyNameToEncrypt = "*** Key name for an object to upload and encrypt ***";
        String keyNameToCopyAndEncrypt = "*** Key name for an unencrypted object to be encrypted by copying ***";
        String copiedObjectKeyName = "*** Key name for the encrypted copy of the unencrypted object ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

            // Upload an object and encrypt it with SSE.
            uploadObjectWithSSEEncryption(s3Client, bucketName, keyNameToEncrypt);

            // Upload a new unencrypted object, then change its encryption state
            // to encrypted by making a copy.
            changeSSEEncryptionStatusByCopying(s3Client,
                    bucketName,
                    keyNameToCopyAndEncrypt,
                    copiedObjectKeyName);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }

    private static void uploadObjectWithSSEEncryption(AmazonS3 s3Client, String bucketName, String keyName) {
        String objectContent = "Test object encrypted with SSE";
        byte[] objectBytes = objectContent.getBytes();

        // Specify server-side encryption.
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(objectBytes.length);
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        PutObjectRequest putRequest = new PutObjectRequest(bucketName,
                keyName,
                new ByteArrayInputStream(objectBytes),
                objectMetadata);

        // Upload the object and check its encryption status.
        PutObjectResult putResult = s3Client.putObject(putRequest);
        System.out.println("Object \"" + keyName + "\" uploaded with SSE.");
        printEncryptionStatus(putResult);
    }

    private static void changeSSEEncryptionStatusByCopying(AmazonS3 s3Client,
            String bucketName,
            String sourceKey,
            String destKey) {
        // Upload a new, unencrypted object.
        PutObjectResult putResult = s3Client.putObject(bucketName, sourceKey, "Object example to encrypt by copying");
        System.out.println("Unencrypted object \"" + sourceKey + "\" uploaded.");
        printEncryptionStatus(putResult);

        // Make a copy of the object and use server-side encryption when storing the
        // copy.
        CopyObjectRequest request = new CopyObjectRequest(bucketName,
                sourceKey,
                bucketName,
                destKey);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
        request.setNewObjectMetadata(objectMetadata);

        // Perform the copy operation and display the copy's encryption status.
        CopyObjectResult response = s3Client.copyObject(request);
        System.out.println("Object \"" + destKey + "\" uploaded with SSE.");
        printEncryptionStatus(response);

        // Delete the original, unencrypted object, leaving only the encrypted copy in
        // Amazon S3.
        s3Client.deleteObject(bucketName, sourceKey);
        System.out.println("Unencrypted object \"" + sourceKey + "\" deleted.");
    }

    private static void printEncryptionStatus(SSEResultBase response) {
        String encryptionStatus = response.getSSEAlgorithm();
        if (encryptionStatus == null) {
            encryptionStatus = "Not encrypted with SSE";
        }
        System.out.println("Object encryption status is: " + encryptionStatus);
    }
}
```

------
#### [ .NET ]

當您上傳物件時，可指示 Amazon S3 加密物件。若要變更現有物件的加密狀態，請複製該物件並刪除來源物件。依預設值，除非您明確地要求對目標物件進行伺服器端加密，否則複製作業不會加密目標。若要在 `CopyObjectRequest` 中指定 SSE-S3，請新增下列項目：

```
 ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
```

如需如何複製物件的工作範例，請參閱「[使用 AWS SDKs](copy-object.md#CopyingObjectsUsingSDKs)」。

下列範例會上傳一個物件。在請求中，此範例會指示 Amazon S3 加密物件。然後，示範擷取物件中繼資料，驗證使用的加密方法。如需有關設定和執行程式碼範例的資訊，請參閱《[適用於 .NET 的 AWS SDK 開發人員指南》中的適用於 .NET 的 SDK 入門](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。 *AWS *

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class SpecifyServerSideEncryptionTest
    {
        private const string bucketName = "*** bucket name ***";
        private const string keyName = "*** key name for object created ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            WritingAnObjectAsync().Wait();
        }

        static async Task WritingAnObjectAsync()
        {
            try
            {
                var putRequest = new PutObjectRequest
                {
                    BucketName = bucketName,
                    Key = keyName,
                    ContentBody = "sample text",
                    ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256
                };

                var putResponse = await client.PutObjectAsync(putRequest);

                // Determine the encryption state of an object.
                GetObjectMetadataRequest metadataRequest = new GetObjectMetadataRequest
                {
                    BucketName = bucketName,
                    Key = keyName
                };
                GetObjectMetadataResponse response = await client.GetObjectMetadataAsync(metadataRequest);
                ServerSideEncryptionMethod objectEncryption = response.ServerSideEncryptionMethod;

                Console.WriteLine("Encryption method used: {0}", objectEncryption.ToString());
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }
    }
}
```

------
#### [ PHP ]

本主題說明如何使用 第 3 版的類別 適用於 PHP 的 AWS SDK ，將 SSE-S3 新增至您上傳至 Amazon S3 的物件。如需適用於 Ruby 的 AWS SDK API 的詳細資訊，請前往[AWS 適用於 Ruby 的 SDK - 第 2 版](https://docs.aws.amazon.com/sdkforruby/api/index.html)。

若要將物件上傳至 Amazon S3，請使用 [Aws\$1S3\$1S3Client::putObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject) 方法。若要將 `x-amz-server-side-encryption` 請求標頭新增至上傳請求，則需使用 `AES256` 值來指定 `ServerSideEncryption` 參數，如以下程式碼範例所示。如需伺服器端加密要求的詳細資訊，請參閱[使用 REST API](#SSEUsingRESTAPI)。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

// $filepath should be an absolute path to a file on disk.
$filepath = '*** Your File Path ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Upload a file with server-side encryption.
$result = $s3->putObject([
    'Bucket'               => $bucket,
    'Key'                  => $keyname,
    'SourceFile'           => $filepath,
    'ServerSideEncryption' => 'AES256',
]);
```

在回應時，Amazon S3 會傳回 `x-amz-server-side-encryption` 標頭，值為用來加密物件資料的加密演算法。

當您使用分段上傳 API 操作上傳大型物件時，可以為要上傳的物件指定 SSE-S3，如下所示：
+ 如果使用低階分段上傳 API 操作，請在呼叫 [ Aws\$1S3\$1S3Client::createMultipartUpload()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) 方法時指定伺服器端加密。若要將 `x-amz-server-side-encryption` 請求標頭新增至請求，則需使用 `AES256` 值來指定 `array` 參數的 `ServerSideEncryption` 金鑰。如需低階分段上傳 API 操作的詳細資訊，請參閱 [使用 AWS SDKs（低階 API)](mpu-upload-object.md#mpu-upload-low-level)。
+ 使用高階分段上傳 API 操作時，請使用 [CreateMultipartUpload](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload) API 操作的 `ServerSideEncryption` 參數來指定伺服器端加密。如需使用 `setOption()` 方法搭配高階分段上傳 API 操作的範例，請參閱 [使用分段上傳來上傳物件](mpu-upload-object.md)。

若要判斷現有物件的加密狀態，請呼叫 [Aws\$1S3\$1S3Client::headObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#headobject) 方法來擷取物件中繼資料，如下列 PHP 程式碼範例所示。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Check which server-side encryption algorithm is used.
$result = $s3->headObject([
    'Bucket' => $bucket,
    'Key'    => $keyname,
]);
echo $result['ServerSideEncryption'];
```

若要變更現有物件的加密狀態，請使用 [Aws\$1S3\$1S3Client::copyObject()](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#copyobject) 方法建立物件複本，並刪除原始物件。除非您使用值為 `AES256` 的 `ServerSideEncryption` 參數來明確請求目的地物件的伺服器端加密，否則 `copyObject()` 預設不會加密目標。下列 PHP 程式碼範例會建立物件複本，並將伺服器端加密新增至複製的物件。

```
 require 'vendor/autoload.php';

use Aws\S3\S3Client;

$sourceBucket = '*** Your Source Bucket Name ***';
$sourceKeyname = '*** Your Source Object Key ***';

$targetBucket = '*** Your Target Bucket Name ***';
$targetKeyname = '*** Your Target Object Key ***';

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

// Copy an object and add server-side encryption.
$s3->copyObject([
    'Bucket'               => $targetBucket,
    'Key'                  => $targetKeyname,
    'CopySource'           => "$sourceBucket/$sourceKeyname",
    'ServerSideEncryption' => 'AES256',
]);
```

如需詳細資訊，請參閱下列主題：
+ [適用於 PHP 的 AWS SDK 適用於 Amazon S3 Aws\$1S3\$1S3Client 類別](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html) 
+ [適用於 PHP 的 AWS SDK 文件](https://aws.amazon.com/documentation/sdk-for-php/)

------
#### [ Ruby ]

使用 適用於 Ruby 的 AWS SDK 上傳物件時，您可以指定使用 SSE-S3 儲存靜態加密的物件。當您讀回物件時，會自動解密。

下列第 3 適用於 Ruby 的 AWS SDK 版範例示範如何指定靜態加密上傳至 Amazon S3 的檔案。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectPutSseWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  def put_object_encrypted(object_content, encryption)
    @object.put(body: object_content, server_side_encryption: encryption)
    true
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't put your content to #{object.key}. Here's why: #{e.message}"
    false
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-encrypted-content"
  object_content = "This is my super-secret content."
  encryption = "AES256"

  wrapper = ObjectPutSseWrapper.new(Aws::S3::Object.new(bucket_name, object_content))
  return unless wrapper.put_object_encrypted(object_content, encryption)

  puts "Put your content into #{bucket_name}:#{object_key} and encrypted it with #{encryption}."
end

run_demo if $PROGRAM_NAME == __FILE__
```

下列程式碼範例示範如何判斷現有物件的加密狀態。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectGetEncryptionWrapper
  attr_reader :object

  # @param object [Aws::S3::Object] An existing Amazon S3 object.
  def initialize(object)
    @object = object
  end

  # Gets the object into memory.
  #
  # @return [Aws::S3::Types::GetObjectOutput, nil] The retrieved object data if successful; otherwise nil.
  def object
    @object.get
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't get object #{@object.key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  bucket_name = "amzn-s3-demo-bucket"
  object_key = "my-object.txt"

  wrapper = ObjectGetEncryptionWrapper.new(Aws::S3::Object.new(bucket_name, object_key))
  obj_data = wrapper.get_object
  return unless obj_data

  encryption = obj_data.server_side_encryption.nil? ? 'no' : obj_data.server_side_encryption
  puts "Object #{object_key} uses #{encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

若存放在 Amazon S3 的物件未使用伺服器端加密，該方法會傳回 `null`。

若要變更現有物件的加密狀態，請複製物件並刪除來源物件。根據預設，除非明確地要求進行伺服器端加密，否則複製方法依預設不會加密目標。您可以在雜湊引數選項中指定 `server_side_encryption` 值，以此請求加密目標物件，如下列 Ruby 程式碼範例所示。該程式碼範例示範如何以 SSE-S3 複製物件及加密複本。

```
require 'aws-sdk-s3'

# Wraps Amazon S3 object actions.
class ObjectCopyEncryptWrapper
  attr_reader :source_object

  # @param source_object [Aws::S3::Object] An existing Amazon S3 object. This is used as the source object for
  #                                        copy actions.
  def initialize(source_object)
    @source_object = source_object
  end

  # Copy the source object to the specified target bucket, rename it with the target key, and encrypt it.
  #
  # @param target_bucket [Aws::S3::Bucket] An existing Amazon S3 bucket where the object is copied.
  # @param target_object_key [String] The key to give the copy of the object.
  # @return [Aws::S3::Object, nil] The copied object when successful; otherwise, nil.
  def copy_object(target_bucket, target_object_key, encryption)
    @source_object.copy_to(bucket: target_bucket.name, key: target_object_key, server_side_encryption: encryption)
    target_bucket.object(target_object_key)
  rescue Aws::Errors::ServiceError => e
    puts "Couldn't copy #{@source_object.key} to #{target_object_key}. Here's why: #{e.message}"
  end
end

# Example usage:
def run_demo
  source_bucket_name = "amzn-s3-demo-bucket1"
  source_key = "my-source-file.txt"
  target_bucket_name = "amzn-s3-demo-bucket2"
  target_key = "my-target-file.txt"
  target_encryption = "AES256"

  source_bucket = Aws::S3::Bucket.new(source_bucket_name)
  wrapper = ObjectCopyEncryptWrapper.new(source_bucket.object(source_key))
  target_bucket = Aws::S3::Bucket.new(target_bucket_name)
  target_object = wrapper.copy_object(target_bucket, target_key, target_encryption)
  return unless target_object

  puts "Copied #{source_key} from #{source_bucket_name} to #{target_object.bucket_name}:#{target_object.key} and "\
       "encrypted the target with #{target_object.server_side_encryption} encryption."
end

run_demo if $PROGRAM_NAME == __FILE__
```

------

## 使用 AWS CLI
<a name="sse-s3-aws-cli"></a>

若要在使用 上傳物件時指定 SSE-S3 AWS CLI，請使用下列範例。

```
aws s3api put-object --bucket amzn-s3-demo-bucket1 --key object-key-name --server-side-encryption AES256  --body file path
```

如需詳細資訊，請參閱 *AWS CLI 參考*中的 [put-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)。若要在使用 複製物件時指定 SSE-S3 AWS CLI，請參閱 [copy-object](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)。

## 使用 CloudFormation
<a name="ss3-s3-cfn"></a>

如需使用 設定加密的範例 CloudFormation，請參閱*AWS CloudFormation 《 使用者指南*》中的使用伺服器端加密搭配 S3 儲存貯體金鑰範例[建立具有預設加密](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_with_default_encryption)`AWS::S3::Bucket ServerSideEncryptionRule`的儲存貯體和建立儲存貯體。 [AWS KMS S3 ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionrule.html#aws-properties-s3-bucket-serversideencryptionrule--examples--Create_a_bucket_using_AWS_KMS_server-side_encryption_with_an_S3_Bucket_Key) 