使用 Amazon S3 受管金鑰 (SSE-S3) 指定伺服器端加密 - Amazon Simple Storage Service

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

使用 Amazon S3 受管金鑰 (SSE-S3) 指定伺服器端加密

重要

Amazon S3 現在將伺服器端加密與 Amazon S3 受管金鑰 (SSE-S3) 套用為 Amazon S3 中每個儲存貯體的基本加密層級。從 2023 年 1 月 5 日起,所有上傳到 Amazon S3 的新物件都會自動加密,無需額外費用,也不會影響效能。S3 儲存貯體預設加密組態和新物件上傳的自動加密狀態可在 AWS CloudTrail 日誌、S3 庫存、S3 儲存鏡頭、Amazon S3 主控台中使用,以及作為和 AWS 開發套件中的額外 Amazon S3 API 回應標頭。 AWS Command Line Interface 如需詳細資訊,請參閱預設加密常見問答集

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

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

您可以使用 S3 主控台、REST API、 AWS 開發套件和 AWS Command Line Interface (AWS CLI) 來指定 SSE-S3。如需詳細資訊,請參閱「對 Amazon S3 儲存貯體設定預設伺服器端加密行為」。

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

注意

如果您變更物件的加密,則會建立新物件來取代舊物件。如果啟用 S3 版本控制,則系統會建立物件的新版本,且現有物件會變成較舊的版本。變更屬性的角色也會成為新物件 (或物件版本) 的擁有者。

變更物件的加密
  1. 登入 AWS Management Console 並開啟 Amazon S3 主控台,網址為 https://console.aws.amazon.com/s3/

  2. 在左側導覽窗格中,選擇 Buckets (儲存貯體)。

  3. Buckets (儲存貯體) 清單中,選擇包含該物件的儲存貯體名稱。

  4. Object (物件) 清單中,選擇您希望新增或變更加密的物件名稱。

    系統會顯示物件的詳細資訊頁面,其中包含數個區段,顯示物件的屬性。

  5. 選擇屬性索引標籤。

  6. 向下捲動至伺服器端加密設定區段,然後選擇編輯

  7. 加密設定底下,選擇使用儲存貯體預設加密設定覆寫儲存貯體預設加密設定

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

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

  9. 選擇 Save changes (儲存變更)

注意

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

建立物件時 (也就是當您上傳新的物件或複製現有物件時),可以指定是否在請求中新增 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 要求標頭。

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

使用 SSE-S3 存放物件時,下列 REST API 操作的回應標頭會傳回 x-amz-server-side-encryption 標頭。

注意

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

使用 AWS 開發套件時,您可以請求 Amazon S3 將伺服器端加密與 Amazon S3 受管加密金鑰搭配使用 (SSE-S3)。本節提供以多種語言使用 AWS SDK 的範例。如需其他 SDK 的資訊,請前往範例程式碼與程式庫

Java

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

使用分段上傳 API 操作時,您也可以要求 SSE-S3 加密。

  • 使用高階分段上傳 API 操作,您可以使用 TransferManager 方法,應用於上傳伺服器端物件加密。您可使用任一接受 ObjectMetadata 為參數的上傳方法。如需詳細資訊,請參閱 使用分段上傳來上傳物件

  • 使用低階分段上傳 API 操作,可以在啟動分段上傳時,指定伺服器端加密。呼叫 ObjectMetadata 的方法,新增 InitiateMultipartUploadRequest.setObjectMetadata() 屬性。如需詳細資訊,請參閱 使用 AWS 軟體開發套件 (低階 API)

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

範例

下列範例示範如何使用 AWS SDK for Java設定伺服器端加密。說明如何執行以下任務:

  • 使用 SSE-S3 上傳新物件。

  • 透過製作物件複本,更改物件的加密狀態 (在此範例中,加密先前未加密過的物件)。

  • 確認物件加密狀態。

如需伺服器端加密的詳細資訊,請參閱「使用 REST API」。如需建立及測試可行範例的說明,請參閱 測試 Amazon S3 Java 程式碼範例

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 軟體開發套件」。

下列範例會上傳一個物件。在請求中,此範例會指示 Amazon S3 加密物件。然後,示範擷取物件中繼資料,驗證使用的加密方法。如需建立及測試工作範例的資訊,請參閱「執行 Amazon S3 .NET 程式碼範例」。

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 版的類別,將 SSE-S3 新增 AWS SDK for PHP 至您上傳到 Amazon S3 的物件。它假設您已經按照的說明進行操作,使用 AWS SDK for PHP 與執行 PHP 的範例並已 AWS SDK for PHP 正確安裝。

若要將物件上傳至 Amazon S3,請使用 Aws\S3\S3Client::putObject() 方法。若要將 x-amz-server-side-encryption 請求標頭新增至上傳請求,則需使用 AES256 值來指定 ServerSideEncryption 參數,如以下程式碼範例所示。如需伺服器端加密要求的詳細資訊,請參閱使用 REST API

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,如下所示:

若要判斷現有物件的加密狀態,請呼叫 Aws\S3\S3Client::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\S3\S3Client::copyObject() 方法建立物件複本,並刪除原始物件。除非您使用值為 AES256ServerSideEncryption 參數來明確請求目的地物件的伺服器端加密,否則 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', ]);

如需詳細資訊,請參閱下列主題:

Ruby

使用上 AWS SDK for Ruby 載物件時,您可以指定使用 SSE-S3 加密儲存物件。當您讀回物件時,會自動解密。

以下第 3 AWS SDK for Ruby 版範例示範如何指定上傳到 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 = "doc-example-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 get_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 = "doc-example-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 = "doc-example-bucket1" source_key = "my-source-file.txt" target_bucket_name = "doc-example-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__

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

aws s3api put-object --bucket DOC-EXAMPLE-BUCKET1 --key object-key-name --server-side-encryption AES256 --body file path

如需詳細資訊,請參閱 AWS CLI 參考中的 put-object。若要在使用複製物件時指定 SSE-S3 AWS CLI,請參閱複製物件。

如需設定加密方式的範例 AWS CloudFormation,請參閱使用AWS CloudFormation 者指AWS::S3::Bucket ServerSideEncryptionRule主題中的使用預設加密建立儲存貯體和使用 AWS KMS 伺服器端加密搭配 S3 儲存貯體金鑰建立儲存貯體。