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

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

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

根據預設,所有 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。

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

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

注意
  • 如果您的物件小於 5 GB,您可以變更物件的加密。如果您的物件大於 5 GB,您必須使用 AWS CLIAWS SDKs 變更物件的加密。

  • 如需變更物件加密所需的其他許可清單,請參閱 Amazon S3 API 操作的必要許可。如需授予此許可的政策範例,請參閱 Amazon S3 的身分型政策範例

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

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

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

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

  4. 動作功能表上,從出現的選項清單中選擇編輯伺服器端加密

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

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

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

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

  8. 其他複製設定下,選擇您要複製來源設定不指定設定指定設定複製來源設定是預設選項。如果您只想要在沒有來源設定屬性的情況下複製物件,請選擇不指定設定。選擇指定設定以指定儲存體類別、ACLs、物件標籤、中繼資料、伺服器端加密和其他檢查總和的設定。

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

注意

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

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

下列 REST 上傳 API 操作接受x-amz-server-side-encryption請求標頭。

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

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

注意

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

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

Java

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

使用分段上傳 SSE 操作上傳物件時,您也可以請求 API-S3 加密:

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

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

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

範例

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

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

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

  • 確認物件加密狀態。

如需伺服器端加密的詳細資訊,請參閱「使用 REST API」。如需建立和測試工作範例的說明,請參閱 AWS SDK for 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 加密物件。若要變更現有物件的加密狀態,請複製該物件並刪除來源物件。依預設值,除非您明確地要求對目標物件進行伺服器端加密,否則複製作業不會加密目標。若要在 中指定 SSE-S3CopyObjectRequest,請新增下列項目:

ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256

如需如何複製物件的工作範例,請參閱「使用 AWS SDKs」。

下列範例會上傳一個物件。在請求中,此範例會指示 Amazon S3 加密物件。然後,示範擷取物件中繼資料,驗證使用的加密方法。如需有關設定和執行程式碼範例的資訊,請參閱 AWS SDK for .NET 中的 Word for .Word 入門 AWS SDK 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 版的類別 AWS SDK for PHP ,將 SSE-S3 新增至您上傳至 Amazon S3 的物件。如需有關 AWS SDK for Ruby API 的詳細資訊,請前往 AWS SDK for Ruby - 第 2 版

若要將物件上傳至 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,如下所示:

  • 當您使用低階分段上傳 API 操作時,當您呼叫 Aws\S3\S3Client::createMultipartUpload() 方法時,請指定伺服器端加密。若要將 x-amz-server-side-encryption 請求標頭新增至請求,則需使用 AES256 值來指定 array 參數的 ServerSideEncryption 金鑰。如需低階分段上傳 API 操作的詳細資訊,請參閱 使用 AWS SDKs (低階 API)

  • 當您使用高階分段上傳 API 操作時,請使用 CreateMultipartUpload API操作的 ServerSideEncryption 參數指定伺服器端加密。如需搭配高階分段上傳 API 操作使用 setOption()方法的範例,請參閱 使用分段上傳來上傳物件

若要判斷現有物件的加密狀態,請呼叫 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 = "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__

若要在使用 上傳物件時指定 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。若要在使用 複製物件時指定 SSE-S3 AWS CLI,請參閱複製物件

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