메뉴
Amazon Simple Storage Service
개발자 안내서 (API Version 2006-03-01)

.NET SDK로 고객 제공 암호화 키를 사용하는 서버 측 암호화 지정

다음 C# 코드 예제에서는 고객 제공 키(SSE-C)를 사용한 서버 측 암호화를 보여줍니다(고객 제공 암호화 키(SSE-C)로 서버 측 암호화를 사용하여 데이터 보호 참조). 이 예제에서는 다음과 같은 작업을 수행하며, 각 작업에서는 요청에 SSE-C 관련 헤더를 지정하는 방법을 보여줍니다.

  • 객체 업로드 - 고객 제공 암호화 키를 사용하여 서버 측 암호화를 요청하는 객체를 업로드합니다.

  • 객체 가져오기 - 앞 단계에서 업로드한 객체를 다운로드합니다. 이 예제는 Amazon S3에 동일한 암호화 정보를 제공해야 객체를 해독하여 반환할 수 있음을 보여줍니다.

  • 객체 메타데이터 가져오기 - 이 요청은 객체 생성 시 지정한 것과 같은 암호화 정보가 있어야 객체의 메타데이터를 검색할 수 있음을 보여줍니다.

  • 객체 복사 - 이 예제는 이전에 업로드한 객체의 사본을 만듭니다. 원본 객체가 SSE-C를 사용하여 저장되었으므로 복사 요청에서도 암호화 정보를 제공해야 합니다. 기본적으로 객체 복사본은 암호화되지 않습니다. 그러나 이 예제에서는 Amazon S3가 SSE-C를 사용하여 암호화된 상태로 객체 복사본을 저장하도록 요청하므로 대상에 대한 SSE-C 암호화 정보도 제공해야 합니다.

참고

멀티파트 업로드 API를 사용하여 대형 객체를 업로드할 때는 다음 예제에서와 같이 요청에 제공한 것과 동일한 암호화 정보를 제공합니다. 멀티파트 업로드 .NET SDK 예제는 멀티파트 업로드용 AWS .NET SDK(상위 수준 API) 사용멀티파트 업로드용 AWS .NET SDK(하위 수준 API) 사용 단원을 참조하십시오.

실제 예제를 작성하여 테스트하는 방법에 대한 자세한 내용은 Amazon S3 .NET 코드 예시 실행 단원을 참조하십시오.

Copy
using System; using System.IO; using System.Security.Cryptography; using Amazon.S3; using Amazon.S3.Model; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace s3.amazon.com.docsamples { class SSEClientEncryptionKeyObjectOperations { static string bucketName = "*** bucket name ***"; static string keyName = "*** object key name for new object ***"; static string copyTargetKeyName = "*** copy operation target object key name ***"; static IAmazonS3 client; public static void Main(string[] args) { using (client = new AmazonS3Client(Amazon.RegionEndpoint.USWest2)) { try { // Create encryption key. Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); string base64Key = Convert.ToBase64String(aesEncryption.Key); // 1. Upload object. PutObjectRequest putObjectRequest = UploadObject(base64Key); // 2. Download object (and also verify content is same as what you uploaded). DownloadObject(base64Key, putObjectRequest); // 3. Get object metadata (and also verify AES256 encryption). GetObjectMetadata(base64Key); // 4. Copy object (both source and target objects use server-side encryption with // customer-provided encryption key. CopyObject(aesEncryption, base64Key); } catch (AmazonS3Exception amazonS3Exception) { if (amazonS3Exception.ErrorCode != null && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity"))) { Console.WriteLine("Check the provided AWS Credentials."); Console.WriteLine( "For service sign up go to http://aws.amazon.com/s3"); } else { Console.WriteLine( "Error occurred. Message:'{0}' when writing an object" , amazonS3Exception.Message); } } } Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } private static void CopyObject(Aes aesEncryption, string base64Key) { aesEncryption.GenerateKey(); string copyBase64Key = Convert.ToBase64String(aesEncryption.Key); CopyObjectRequest copyRequest = new CopyObjectRequest { SourceBucket = bucketName, SourceKey = keyName, DestinationBucket = bucketName, DestinationKey = copyTargetKeyName, // Source object encryption information. CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, CopySourceServerSideEncryptionCustomerProvidedKey = base64Key, // Target object encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = copyBase64Key }; client.CopyObject(copyRequest); } private static void DownloadObject(string base64Key, PutObjectRequest putObjectRequest) { GetObjectRequest getObjectRequest = new GetObjectRequest { BucketName = bucketName, Key = keyName, // Provide encryption information of the object stored in S3. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; using (GetObjectResponse getResponse = client.GetObject(getObjectRequest)) using (StreamReader reader = new StreamReader(getResponse.ResponseStream)) { string content = reader.ReadToEnd(); Assert.AreEqual(putObjectRequest.ContentBody, content); Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getResponse.ServerSideEncryptionCustomerMethod); } } private static void GetObjectMetadata(string base64Key) { GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest { BucketName = bucketName, Key = keyName, // Object stored in S3 is encrypted. So provide necessary encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; GetObjectMetadataResponse getObjectMetadataResponse = client.GetObjectMetadata(getObjectMetadataRequest); Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getObjectMetadataResponse.ServerSideEncryptionCustomerMethod); } private static PutObjectRequest UploadObject(string base64Key) { PutObjectRequest putObjectRequest = new PutObjectRequest { BucketName = bucketName, Key = keyName, ContentBody = "sample text", ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; PutObjectResponse putObjectResponse = client.PutObject(putObjectRequest); return putObjectRequest; } } }

기타 Amazon S3 작업 및 SSE-C

앞 단원의 예제에서는 PUT, GET, Head 및 Copy 작업에서 고객 제공 키(SSE-C)를 사용하는 서버 측 암호화를 요청하는 방법을 알아보았으며, 이 단원에서는 SSE-C를 지원하는 기타 API에 대해 소개합니다.

멀티파트 업로드 API를 사용하여 대형 객체를 업로드할 수 있습니다(멀티파트 업로드 API를 사용한 객체 업로드 참조). 상위 수준 또는 하위 수준의 API를 사용하여 대형 객체를 업로드할 수 있습니다. 이들 API는 요청의 암호화 관련 헤더를 지원합니다.

  • 상위 수준의 Transfer-Utility API를 사용할 때는 아래와 같이 TransferUtilityUploadRequest에 암호화 관련 헤더를 제공합니다. 코드 예제는 멀티파트 업로드용 AWS .NET SDK(상위 수준 API) 사용 단원을 참조하십시오.

    Copy
    TransferUtilityUploadRequest request = new TransferUtilityUploadRequest() { FilePath = filePath, BucketName = existingBucketName, Key = keyName, // Provide encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, };
  • 하위 수준의 API를 사용할 경우 멀티파트 업로드 요청을 시작할 때 암호화 관련 정보를 제공하고, 이후 부분 업로드 요청 시에도 동일한 암호화 정보를 제공합니다. 멀티파트 업로드 완료 요청에서는 암호화 관련 헤더를 제공할 필요가 없습니다. 예제는 멀티파트 업로드용 AWS .NET SDK(하위 수준 API) 사용를 참조하십시오.

    다음은 기존 대형 객체의 복사본을 만드는 하위 수준의 멀티파트 업로드 예제입니다. 이 예제에서 복사된 객체는 SSE-C를 사용하여 Amazon S3에 저장되고, 대상 객체 또한 SSE-C를 사용하여 저장됩니다. 이 예제에서는 다음 작업을 수행합니다.

    • 암호화 키와 관련 정보를 제공하여 멀티파트 업로드 요청을 시작합니다.

    • CopyPartRequest에 원본 및 대상 객체 암호화 키와 관련 정보를 제공합니다.

    • 객체 메타데이터를 검색하여 복사할 원본 객체의 크기를 확인합니다.

    • 5MB 단위로 객체를 업로드합니다.

    Copy
    using System; using System.Collections.Generic; using System.Security.Cryptography; using Amazon.S3; using Amazon.S3.Model; namespace s3.amazon.com.docsamples { class SSECLowLevelMPUcopyObject { static string existingBucketName = "*** bucket name ***"; static string sourceKeyName = "*** key name ***"; static string targetKeyName = "*** key name ***"; static void Main(string[] args) { IAmazonS3 s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1); List<CopyPartResponse> uploadResponses = new List<CopyPartResponse>(); Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); string base64Key = Convert.ToBase64String(aesEncryption.Key); // 1. Initialize. InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = existingBucketName, Key = targetKeyName, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, }; InitiateMultipartUploadResponse initResponse = s3Client.InitiateMultipartUpload(initiateRequest); // 2. Upload Parts. long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB long firstByte = 0; long lastByte = partSize; try { // First find source object size. Because object is stored encrypted with // customer provided key you need to provide encryption information in your request. GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest() { BucketName = existingBucketName, Key = sourceKeyName, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = "***source object encryption key ***" }; GetObjectMetadataResponse getObjectMetadataResponse = s3Client.GetObjectMetadata(getObjectMetadataRequest); long filePosition = 0; for (int i = 1; filePosition < getObjectMetadataResponse.ContentLength; i++) { CopyPartRequest copyPartRequest = new CopyPartRequest { UploadId = initResponse.UploadId, // Source. SourceBucket = existingBucketName, SourceKey = sourceKeyName, // Source object is stored using SSE-C. Provide encryption information. CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, CopySourceServerSideEncryptionCustomerProvidedKey = "***source object encryption key ***", FirstByte = firstByte, // If the last part is smaller then our normal part size then use the remaining size. LastByte = lastByte > getObjectMetadataResponse.ContentLength ? getObjectMetadataResponse.ContentLength - 1 : lastByte, // Target. DestinationBucket = existingBucketName, DestinationKey = targetKeyName, PartNumber = i, // Ecnryption information for the target object. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; uploadResponses.Add(s3Client.CopyPart(copyPartRequest)); filePosition += partSize; firstByte += partSize; lastByte += partSize; } // Step 3: complete. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest { BucketName = existingBucketName, Key = targetKeyName, UploadId = initResponse.UploadId, }; completeRequest.AddPartETags(uploadResponses); CompleteMultipartUploadResponse completeUploadResponse = s3Client.CompleteMultipartUpload(completeRequest); } catch (Exception exception) { Console.WriteLine("Exception occurred: {0}", exception.Message); AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest { BucketName = existingBucketName, Key = targetKeyName, UploadId = initResponse.UploadId }; s3Client.AbortMultipartUpload(abortMPURequest); } } } }

이 페이지에서: