Menggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C) SSE - Amazon Simple Storage Service

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C) SSE

Enkripsi sisi-server adalah tentang melindungi data diam. Enkripsi di sisi server hanya mengenkripsi data objek, bukan metadata objek. Dengan menggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (SSE-C), Anda dapat menyimpan data yang dienkripsi dengan kunci enkripsi Anda sendiri. Dengan kunci enkripsi yang Anda sediakan sebagai bagian dari permintaan Anda, Amazon S3 mengelola enkripsi data saat menulis ke disk dan dekripsi data saat Anda mengakses objek Anda. Oleh karena itu, Anda tidak perlu menyimpan kode apa pun untuk melakukan enkripsi dan dekripsi data. Satu-satunya hal yang perlu Anda lakukan adalah mengelola kunci enkripsi yang Anda berikan.

Saat Anda mengunggah objek, Amazon S3 menggunakan kunci enkripsi yang Anda berikan untuk menerapkan enkripsi AES -256 ke data Anda. Amazon S3 kemudian menghapus kunci enkripsi dari memori. Saat mengambil sebuah objek, Anda harus memberikan kunci enkripsi yang sama sebagai bagian dari permintaan Anda. Amazon S3 pertama-tama memverifikasi bahwa kunci enkripsi yang Anda berikan cocok, lalu mendekripsi objek sebelum mengembalikan data objek kepada Anda.

Tidak ada biaya tambahan untuk menggunakan SSE -C. Namun, permintaan untuk mengonfigurasi dan menggunakan SSE -C dikenakan biaya permintaan Amazon S3 standar. Untuk informasi tentang harga, lihat Harga Amazon S3.

catatan

Amazon S3 tidak menyimpan kunci enkripsi yang Anda sediakan. Sebagai gantinya, ia menyimpan nilai Message Authentication Code (HMAC) berbasis Hash yang diasinkan secara acak dari kunci enkripsi untuk memvalidasi permintaan masa depan. HMACNilai asin tidak dapat digunakan untuk menurunkan nilai kunci enkripsi atau untuk mendekripsi isi objek terenkripsi. Artinya, jika Anda kehilangan kunci enkripsi, Anda akan kehilangan objek.

S3 Replikasi mendukung objek yang dienkripsi dengan -C. SSE Untuk informasi selengkapnya tentang mereplikasi objek terenkripsi, lihat. Mereplikasi objek terenkripsi (SSE-C, SSE -S3, -, -) SSE KMS DSSE KMS

Untuk informasi selengkapnya tentang SSE -C, lihat topik berikut.

SSEIkhtisar -C

Bagian ini memberikan gambaran umum tentang SSE -C. Saat menggunakan SSE -C, ingatlah pertimbangan berikut.

  • Anda harus menggunakan HTTPS.

    penting

    Amazon S3 menolak permintaan apa pun yang dibuat HTTP saat menggunakan -C. SSE Untuk pertimbangan keamanan, kami menyarankan Anda mempertimbangkan kunci apa pun yang Anda kirimkan secara keliru HTTP untuk dikompromikan. Buang kuncinya dan putar seperlunya.

  • Entity tag (ETag) dalam respon bukanlah MD5 hash dari data objek.

  • Anda mengelola pemetaan kunci enkripsi mana yang digunakan untuk mengenkripsi objek yang ingin dituju. Amazon S3 tidak menyimpan kunci enkripsi. Anda bertanggung jawab untuk melacak kunci enkripsi yang Anda berikan untuk objek yang ingin dituju.

    • Jika versi bucket Anda diaktifkan dengan Penentuan Versi, setiap versi objek yang Anda unggah menggunakan fitur ini dapat memiliki kunci enkripsinya sendiri. Anda bertanggung jawab untuk melacak kunci enkripsi yang Anda berikan untuk objek yang ingin dituju.

    • Karena Anda mengelola kunci enkripsi di sisi klien, Anda mengelola perlindungan tambahan, seperti rotasi utama, di sisi klien.

    Awas

    Jika Anda kehilangan kunci enkripsi, setiap permintaan GET untuk objek tanpa kunci enkripsi akan gagal, dan Anda kehilangan objek tersebut.

Membutuhkan dan membatasi -C SSE

Untuk mewajibkan SSE -C untuk semua objek di bucket Amazon S3 tertentu, Anda dapat menggunakan kebijakan bucket.

Misalnya, kebijakan bucket berikut menolak izin upload object (s3:PutObject) untuk semua permintaan yang tidak menyertakan x-amz-server-side-encryption-customer-algorithm header yang meminta SSE -C.

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

Anda juga dapat menggunakan kebijakan untuk membatasi enkripsi di sisi server pada semua objek di bucket Amazon S3 tertentu. Misalnya, kebijakan bucket berikut menolak izin upload object (s3:PutObject) untuk semua orang jika permintaan menyertakan x-amz-server-side-encryption-customer-algorithm header yang meminta SSE -C.

{ "Version": "2012-10-17", "Id": "PutObjectPolicy", "Statement": [ { "Sid": "RestrictSSECObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption-customer-algorithm": "false" } } } ] }
penting

Jika Anda menggunakan kebijakan bucket untuk mewajibkan SSE -C aktifs3:PutObject, Anda harus menyertakan x-amz-server-side-encryption-customer-algorithm header di semua permintaan unggahan multibagian (CreateMultipartUpload, UploadPart, danCompleteMultipartUpload).

Presigned URLs dan SSE -C

Anda dapat menghasilkan presigned URL yang dapat digunakan untuk operasi seperti mengunggah objek baru, mengambil objek yang ada, atau mengambil metadata objek. URLsDukungan presigned SSE -C sebagai berikut:

  • Saat membuat presignedURL, Anda harus menentukan algoritma dengan menggunakan x-amz-server-side​-encryption​-customer-algorithm header dalam perhitungan tanda tangan.

  • Saat menggunakan presigned URL untuk mengunggah objek baru, mengambil objek yang ada, atau hanya mengambil metadata objek, Anda harus menyediakan semua header enkripsi dalam permintaan aplikasi klien Anda.

    catatan

    Untuk objek SSE non--C, Anda dapat menghasilkan presigned URL dan langsung menempelkannya URL ke browser untuk mengakses data.

    Namun, Anda tidak dapat melakukan ini untuk objek SSE -C, karena selain presignedURL, Anda juga harus menyertakan HTTP header yang khusus untuk SSE objek -C. Oleh karena itu, Anda dapat menggunakan presigned URLs for SSE -C objek hanya secara terprogram.

Untuk informasi lebih lanjut tentang presignedURLs, lihatBekerja dengan presigned URLs.

Menentukan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C) SSE

Pada saat pembuatan objek dengan RESTAPI, Anda dapat menentukan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C). SSE Bila Anda menggunakan SSE -C, Anda harus memberikan informasi kunci enkripsi menggunakan header permintaan berikut.

Nama Deskripsi
x-amz-server-side​-encryption​-customer-algorithm

Gunakan header ini untuk menentukan algoritma enkripsi. Nilai header harus berupa AES256.

x-amz-server-side​-encryption​-customer-key

Gunakan header ini untuk menyediakan kunci enkripsi 256 bit, berkode base64 agar Amazon S3 dapat digunakan untuk mengenkripsi atau mendekripsi data Anda.

x-amz-server-side​-encryption​-customer-key-MD5

Gunakan header ini untuk memberikan MD5 intisari 128-bit yang dikodekan base64 dari kunci enkripsi menurut 1321. RFC Amazon S3 menggunakan header ini untuk pemeriksaan integritas pesan guna memastikan bahwa kunci enkripsi dikirimkan tanpa kesalahan.

Anda dapat menggunakan pustaka AWS SDK pembungkus untuk menambahkan header ini ke permintaan Anda. Jika perlu, Anda dapat melakukan REST API panggilan Amazon S3 langsung di aplikasi Anda.

catatan

Anda tidak dapat menggunakan konsol Amazon S3 untuk mengunggah objek dan meminta SSE -C. Anda juga tidak dapat menggunakan konsol untuk memperbarui (misalnya, mengubah kelas penyimpanan atau menambahkan metadata) objek yang ada yang disimpan menggunakan SSE -C.

Amazon S3 sisanya APIs yang mendukung -C SSE

Amazon S3 berikut APIs mendukung enkripsi sisi server dengan kunci enkripsi yang disediakan pelanggan (-C). SSE

  • GEToperasi — Saat mengambil objek menggunakan GET API (lihat GETObjek), Anda dapat menentukan header permintaan.

  • HEADoperasi — Untuk mengambil metadata objek menggunakan HEAD API (lihat HEADObject), Anda dapat menentukan header permintaan ini.

  • PUToperasi — Saat mengunggah data menggunakan PUT Object API (lihat PUTObject), Anda dapat menentukan header permintaan ini.

  • Unggah Multipart - Saat mengunggah objek besar menggunakan unggahan multibagianAPI, Anda dapat menentukan header ini. Anda menentukan header ini dalam permintaan inisiasi (lihat Mulai Pengunggahan Multibagian) dan setiap permintaan pengunggahan bagian berikutnya (lihat Unggah Bagian atau Unggah Bagian-Salin). Untuk setiap permintaan unggahan bagian, informasi enkripsi harus sama dengan yang Anda berikan dalam permintaan unggahan multibagian.

  • POSTOperasi — Saat menggunakan POST operasi untuk mengunggah objek (lihat POSTObjek), alih-alih header permintaan, Anda memberikan informasi yang sama di bidang formulir.

  • Salin operasi - Ketika Anda menyalin objek (lihat PUTObject - Copy), Anda memiliki objek sumber dan objek target:

    • Jika Anda ingin objek target dienkripsi menggunakan enkripsi sisi server dengan kunci AWS terkelola, Anda harus memberikan header permintaan. x-amz-server-side​-encryption

    • Jika Anda ingin objek target dienkripsi menggunakan SSE -C, Anda harus memberikan informasi enkripsi menggunakan tiga header yang dijelaskan dalam tabel sebelumnya.

    • Jika objek sumber dienkripsi menggunakan SSE -C, Anda harus memberikan informasi kunci enkripsi menggunakan header berikut sehingga Amazon S3 dapat mendekripsi objek untuk disalin.

      Nama Deskripsi
      x-amz-copy-source​-server-side​-encryption​-customer-algorithm

      Sertakan header ini untuk menentukan algoritma yang harus digunakan Amazon S3 untuk mendekripsi objek sumber. Nilai ini harus berupa AES256.

      x-amz-copy-source​-server-side​-encryption​-customer-key

      Sertakan header ini untuk menyediakan kunci enkripsi berenkode base64 untuk Amazon S3 untuk digunakan untuk mendekripsi objek sumber. Kunci enkripsi ini harus berupa kunci yang Anda berikan kepada Amazon S3 saat membuat objek sumber. Jika tidak, Amazon S3 tidak dapat mendekripsi objeknya.

      x-amz-copy-source-​server-side​-encryption​-customer-key-MD5

      Sertakan header ini untuk memberikan MD5 intisari 128-bit yang dikodekan base64 dari kunci enkripsi sesuai dengan 1321. RFC

Contoh berikut menunjukkan cara meminta enkripsi sisi server dengan kunci yang disediakan pelanggan (SSE-C) untuk objek. Contoh melakukan operasi berikut. Setiap operasi menunjukkan cara menentukan header SSE terkait -C dalam permintaan:

  • Put objek–Mengunggah objek dan meminta enkripsi di sisi server menggunakan kunci enkripsi yang disediakan pelanggan.

  • Get object–Mengunduh objek yang diunggah dalam langkah sebelumnya. Dalam permintaan tersebut, Anda memberikan informasi enkripsi yang sama dengan yang Anda berikan saat unggah objek tersebut. Amazon S3 memerlukan informasi ini untuk mendekripsi objek sehingga dapat mengembalikannya kepada Anda.

  • Get object metadata–Mengambil metadata objek. Anda memberikan informasi enkripsi yang sama, yang digunakan saat objek tersebut dibuat.

  • Copy object–Membuat salinan dari objek yang diunggah sebelumnya. Karena objek sumber disimpan menggunakan SSE -C, Anda harus memberikan informasi enkripsi dalam permintaan salinan Anda. Secara default, Amazon S3 mengenkripsi salinan objek hanya jika Anda secara eksplisit memintanya. Contoh ini mengarahkan Amazon S3 untuk menyimpan salinan objek yang dienkripsi.

Java
catatan

Contoh ini menunjukkan cara untuk mengunggah objek dalam satu operasi. Saat menggunakan Unggah Multipart API untuk mengunggah objek besar, Anda memberikan informasi enkripsi dengan cara yang sama seperti yang ditunjukkan dalam contoh ini. Untuk contoh unggahan multipart yang menggunakan file AWS SDK for Java, lihat. Pengunggahan objek menggunakan unggahan multibagian

Untuk menambahkan informasi enkripsi yang diperlukan, Anda menyertakan SSECustomerKey dalam permintaan Anda. Untuk informasi lebih lanjut tentang SSECustomerKey kelas, lihat REST API bagian.

Untuk informasi tentang SSE -C, lihatMenggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C) SSE. Untuk petunjuk cara membuat dan menguji sampel yang berfungsi, lihat Memulai di Panduan AWS SDK for Java Pengembang.

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.model.*; import javax.crypto.KeyGenerator; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class ServerSideEncryptionUsingClientSideEncryptionKey { private static SSECustomerKey SSE_KEY; private static AmazonS3 S3_CLIENT; private static KeyGenerator KEY_GENERATOR; public static void main(String[] args) throws IOException, NoSuchAlgorithmException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String keyName = "*** Key name ***"; String uploadFileName = "*** File path ***"; String targetKeyName = "*** Target key name ***"; // Create an encryption key. KEY_GENERATOR = KeyGenerator.getInstance("AES"); KEY_GENERATOR.init(256, new SecureRandom()); SSE_KEY = new SSECustomerKey(KEY_GENERATOR.generateKey()); try { S3_CLIENT = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Upload an object. uploadObject(bucketName, keyName, new File(uploadFileName)); // Download the object. downloadObject(bucketName, keyName); // Verify that the object is properly encrypted by attempting to retrieve it // using the encryption key. retrieveObjectMetadata(bucketName, keyName); // Copy the object into a new object that also uses SSE-C. copyObject(bucketName, keyName, targetKeyName); } 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 uploadObject(String bucketName, String keyName, File file) { PutObjectRequest putRequest = new PutObjectRequest(bucketName, keyName, file).withSSECustomerKey(SSE_KEY); S3_CLIENT.putObject(putRequest); System.out.println("Object uploaded"); } private static void downloadObject(String bucketName, String keyName) throws IOException { GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, keyName).withSSECustomerKey(SSE_KEY); S3Object object = S3_CLIENT.getObject(getObjectRequest); System.out.println("Object content: "); displayTextInputStream(object.getObjectContent()); } private static void retrieveObjectMetadata(String bucketName, String keyName) { GetObjectMetadataRequest getMetadataRequest = new GetObjectMetadataRequest(bucketName, keyName) .withSSECustomerKey(SSE_KEY); ObjectMetadata objectMetadata = S3_CLIENT.getObjectMetadata(getMetadataRequest); System.out.println("Metadata retrieved. Object size: " + objectMetadata.getContentLength()); } private static void copyObject(String bucketName, String keyName, String targetKeyName) throws NoSuchAlgorithmException { // Create a new encryption key for target so that the target is saved using // SSE-C. SSECustomerKey newSSEKey = new SSECustomerKey(KEY_GENERATOR.generateKey()); CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName) .withSourceSSECustomerKey(SSE_KEY) .withDestinationSSECustomerKey(newSSEKey); S3_CLIENT.copyObject(copyRequest); System.out.println("Object copied"); } private static void displayTextInputStream(S3ObjectInputStream input) throws IOException { // Read one line at a time from the input stream and display each line. BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } System.out.println(); } }
.NET
catatan

Untuk contoh mengunggah objek besar menggunakan unggahan multipartAPI, lihat Pengunggahan objek menggunakan unggahan multibagian dan. Menggunakan AWS SDKs (tingkat rendahAPI)

Untuk informasi tentang SSE -C, lihatMenggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (-C) SSE. Untuk informasi tentang menyiapkan dan menjalankan contoh kode, lihat Memulai dengan AWS SDK for. NETdi AWS SDKuntuk. NETPanduan Pengembang.

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.IO; using System.Security.Cryptography; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class SSEClientEncryptionKeyObjectOperationsTest { private const string bucketName = "*** bucket name ***"; private const string keyName = "*** key name for new object created ***"; private const string copyTargetKeyName = "*** key name for object copy ***"; // 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); ObjectOpsUsingClientEncryptionKeyAsync().Wait(); } private static async Task ObjectOpsUsingClientEncryptionKeyAsync() { try { // Create an encryption key. Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); string base64Key = Convert.ToBase64String(aesEncryption.Key); // 1. Upload the object. PutObjectRequest putObjectRequest = await UploadObjectAsync(base64Key); // 2. Download the object and verify that its contents matches what you uploaded. await DownloadObjectAsync(base64Key, putObjectRequest); // 3. Get object metadata and verify that the object uses AES-256 encryption. await GetObjectMetadataAsync(base64Key); // 4. Copy both the source and target objects using server-side encryption with // a customer-provided encryption key. await CopyObjectAsync(aesEncryption, base64Key); } 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); } } private static async Task<PutObjectRequest> UploadObjectAsync(string base64Key) { PutObjectRequest putObjectRequest = new PutObjectRequest { BucketName = bucketName, Key = keyName, ContentBody = "sample text", ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; PutObjectResponse putObjectResponse = await client.PutObjectAsync(putObjectRequest); return putObjectRequest; } private static async Task DownloadObjectAsync(string base64Key, PutObjectRequest putObjectRequest) { GetObjectRequest getObjectRequest = new GetObjectRequest { BucketName = bucketName, Key = keyName, // Provide encryption information for the object stored in Amazon S3. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; using (GetObjectResponse getResponse = await client.GetObjectAsync(getObjectRequest)) using (StreamReader reader = new StreamReader(getResponse.ResponseStream)) { string content = reader.ReadToEnd(); if (String.Compare(putObjectRequest.ContentBody, content) == 0) Console.WriteLine("Object content is same as we uploaded"); else Console.WriteLine("Error...Object content is not same."); if (getResponse.ServerSideEncryptionCustomerMethod == ServerSideEncryptionCustomerMethod.AES256) Console.WriteLine("Object encryption method is AES256, same as we set"); else Console.WriteLine("Error...Object encryption method is not the same as AES256 we set"); // Assert.AreEqual(putObjectRequest.ContentBody, content); // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getResponse.ServerSideEncryptionCustomerMethod); } } private static async Task GetObjectMetadataAsync(string base64Key) { GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest { BucketName = bucketName, Key = keyName, // The object stored in Amazon S3 is encrypted, so provide the necessary encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; GetObjectMetadataResponse getObjectMetadataResponse = await client.GetObjectMetadataAsync(getObjectMetadataRequest); Console.WriteLine("The object metadata show encryption method used is: {0}", getObjectMetadataResponse.ServerSideEncryptionCustomerMethod); // Assert.AreEqual(ServerSideEncryptionCustomerMethod.AES256, getObjectMetadataResponse.ServerSideEncryptionCustomerMethod); } private static async Task CopyObjectAsync(Aes aesEncryption, string base64Key) { aesEncryption.GenerateKey(); string copyBase64Key = Convert.ToBase64String(aesEncryption.Key); CopyObjectRequest copyRequest = new CopyObjectRequest { SourceBucket = bucketName, SourceKey = keyName, DestinationBucket = bucketName, DestinationKey = copyTargetKeyName, // Information about the source object's encryption. CopySourceServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, CopySourceServerSideEncryptionCustomerProvidedKey = base64Key, // Information about the target object's encryption. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = copyBase64Key }; await client.CopyObjectAsync(copyRequest); } } }

Contoh di bagian sebelumnya menunjukkan cara meminta enkripsi sisi server dengan kunci yang disediakan pelanggan (SSE-C) dalam operasi,, Head, dan Copy. PUT GET Bagian ini menjelaskan Amazon S3 lain APIs yang mendukung SSE -C.

Java

Untuk mengunggah objek besar, Anda dapat menggunakan upload multipart API (lihatMengunggah dan menyalin objek menggunakan unggahan multibagian). Anda dapat menggunakan level tinggi atau level rendah APIs untuk mengunggah objek besar. Ini APIs mendukung header terkait enkripsi dalam permintaan.

  • Saat menggunakan level tinggi TransferManagerAPI, Anda menyediakan header khusus enkripsi di (lihat). PutObjectRequest Pengunggahan objek menggunakan unggahan multibagian

  • Saat menggunakan tingkat rendahAPI, Anda memberikan informasi terkait enkripsi diInitiateMultipartUploadRequest, diikuti oleh informasi enkripsi yang identik di masing-masing. UploadPartRequest Anda tidak perlu memberikan header kustom enkripsi apa pun dalam CompleteMultipartUploadRequest Anda. Sebagai contoh, lihat Menggunakan AWS SDKs (tingkat rendahAPI).

Contoh berikut digunakan TransferManager untuk membuat objek dan menunjukkan bagaimana memberikan informasi terkait SSE -C. Contoh ini melakukan hal berikut:

  • Membuat objek menggunakan metode TransferManager.upload(). Di dalam instans PutObjectRequest, Anda memberikan informasi kunci enkripsi untuk meminta. Amazon S3 mengenkripsi objek menggunakan kunci yang disediakan pelanggan.

  • Membuat salinan objek dengan memanggil metode TransferManager.copy(). Contoh tersebut mengarahkan Amazon S3 untuk mengenkripsi salinan objek menggunakan SSECustomerKey yang baru. Karena objek sumber dienkripsi menggunakan SSE -C, CopyObjectRequest juga menyediakan kunci enkripsi objek sumber sehingga Amazon S3 dapat mendekripsi objek sebelum menyalinnya.

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.model.CopyObjectRequest; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.SSECustomerKey; import com.amazonaws.services.s3.transfer.Copy; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.TransferManagerBuilder; import com.amazonaws.services.s3.transfer.Upload; import javax.crypto.KeyGenerator; import java.io.File; import java.security.SecureRandom; public class ServerSideEncryptionCopyObjectUsingHLwithSSEC { public static void main(String[] args) throws Exception { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String fileToUpload = "*** File path ***"; String keyName = "*** New object key name ***"; String targetKeyName = "*** Key name for object copy ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); TransferManager tm = TransferManagerBuilder.standard() .withS3Client(s3Client) .build(); // Create an object from a file. PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, new File(fileToUpload)); // Create an encryption key. KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(256, new SecureRandom()); SSECustomerKey sseCustomerEncryptionKey = new SSECustomerKey(keyGenerator.generateKey()); // Upload the object. TransferManager uploads asynchronously, so this call // returns immediately. putObjectRequest.setSSECustomerKey(sseCustomerEncryptionKey); Upload upload = tm.upload(putObjectRequest); // Optionally, wait for the upload to finish before continuing. upload.waitForCompletion(); System.out.println("Object created."); // Copy the object and store the copy using SSE-C with a new key. CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, keyName, bucketName, targetKeyName); SSECustomerKey sseTargetObjectEncryptionKey = new SSECustomerKey(keyGenerator.generateKey()); copyObjectRequest.setSourceSSECustomerKey(sseCustomerEncryptionKey); copyObjectRequest.setDestinationSSECustomerKey(sseTargetObjectEncryptionKey); // Copy the object. TransferManager copies asynchronously, so this call returns // immediately. Copy copy = tm.copy(copyObjectRequest); // Optionally, wait for the upload to finish before continuing. copy.waitForCompletion(); System.out.println("Copy complete."); } 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(); } } }
.NET

Untuk mengunggah objek besar, Anda dapat menggunakan upload multipart API (lihatMengunggah dan menyalin objek menggunakan unggahan multibagian). AWS SDKuntuk. NETmenyediakan tingkat tinggi atau tingkat rendah APIs untuk mengunggah objek besar. Ini APIs mendukung header terkait enkripsi dalam permintaan.

  • Saat menggunakan level tinggi Transfer-Utility API, Anda memberikan header khusus enkripsi seperti yang ditunjukkan. TransferUtilityUploadRequest Untuk contoh kode, lihat Pengunggahan objek menggunakan unggahan multibagian.

    TransferUtilityUploadRequest request = new TransferUtilityUploadRequest() { FilePath = filePath, BucketName = existingBucketName, Key = keyName, // Provide encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, };
  • Saat menggunakan tingkat rendahAPI, Anda memberikan informasi terkait enkripsi dalam permintaan unggahan multibagian inisiasi, diikuti oleh informasi enkripsi identik dalam permintaan bagian unggahan berikutnya. Anda tidak perlu memberikan header kustom enkripsi apa pun dalam permintaan pengunggahan multibagian lengkap Anda. Sebagai contoh, lihat Menggunakan AWS SDKs (tingkat rendahAPI).

    Berikut ini adalah contoh pengunggahan multibagian tingkat rendah yang membuat salinan objek besar yang sudah ada. Dalam contoh, objek yang akan disalin disimpan di Amazon S3 SSE menggunakan -C, dan Anda ingin menyimpan objek target juga menggunakan -C. SSE Dalam contoh, Anda melakukan hal berikut:

    • Mulai permintaan pengunggahan multibagian dengan memberikan kunci enkripsi dan informasi terkait.

    • Menyediakan kunci enkripsi objek sumber dan sasaran serta informasi terkait dalam CopyPartRequest.

    • Dapatkan ukuran objek sumber yang akan disalin dengan mengambil metadata objek.

    • Unggah objek ke dalam bagian 5 MB.

    using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class SSECLowLevelMPUcopyObjectTest { private const string existingBucketName = "*** bucket name ***"; private const string sourceKeyName = "*** source object key name ***"; private const string targetKeyName = "*** key name for the target object ***"; private const string filePath = @"*** file path ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 s3Client; static void Main() { s3Client = new AmazonS3Client(bucketRegion); CopyObjClientEncryptionKeyAsync().Wait(); } private static async Task CopyObjClientEncryptionKeyAsync() { Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); string base64Key = Convert.ToBase64String(aesEncryption.Key); await CreateSampleObjUsingClientEncryptionKeyAsync(base64Key, s3Client); await CopyObjectAsync(s3Client, base64Key); } private static async Task CopyObjectAsync(IAmazonS3 s3Client, string base64Key) { List<CopyPartResponse> uploadResponses = new List<CopyPartResponse>(); // 1. Initialize. InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = existingBucketName, Key = targetKeyName, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, }; InitiateMultipartUploadResponse initResponse = await s3Client.InitiateMultipartUploadAsync(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 = base64Key // " * **source object encryption key ***" }; GetObjectMetadataResponse getObjectMetadataResponse = await s3Client.GetObjectMetadataAsync(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 = base64Key, //"***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, // Encryption information for the target object. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; uploadResponses.Add(await s3Client.CopyPartAsync(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 = await s3Client.CompleteMultipartUploadAsync(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); } } private static async Task CreateSampleObjUsingClientEncryptionKeyAsync(string base64Key, IAmazonS3 s3Client) { // List to store upload part responses. List<UploadPartResponse> uploadResponses = new List<UploadPartResponse>(); // 1. Initialize. InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; InitiateMultipartUploadResponse initResponse = await s3Client.InitiateMultipartUploadAsync(initiateRequest); // 2. Upload Parts. long contentLength = new FileInfo(filePath).Length; long partSize = 5 * (long)Math.Pow(2, 20); // 5 MB try { long filePosition = 0; for (int i = 1; filePosition < contentLength; i++) { UploadPartRequest uploadRequest = new UploadPartRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId, PartNumber = i, PartSize = partSize, FilePosition = filePosition, FilePath = filePath, ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key }; // Upload part and add response to our list. uploadResponses.Add(await s3Client.UploadPartAsync(uploadRequest)); filePosition += partSize; } // Step 3: complete. CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId, //PartETags = new List<PartETag>(uploadResponses) }; completeRequest.AddPartETags(uploadResponses); CompleteMultipartUploadResponse completeUploadResponse = await s3Client.CompleteMultipartUploadAsync(completeRequest); } catch (Exception exception) { Console.WriteLine("Exception occurred: {0}", exception.Message); AbortMultipartUploadRequest abortMPURequest = new AbortMultipartUploadRequest { BucketName = existingBucketName, Key = sourceKeyName, UploadId = initResponse.UploadId }; await s3Client.AbortMultipartUploadAsync(abortMPURequest); } } } }