Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menentukan enkripsi di sisi server dengan kunci yang disediakan pelanggan (SSE-C)
Untuk menggunakan enkripsi sisi server dengan kunci yang disediakan pelanggan (SSE-C) terlebih dahulu pastikan bahwa SSE-C bukan jenis enkripsi yang diblokir dalam konfigurasi enkripsi default bucket tujuan umum Amazon S3 Anda. Jika diblokir, Anda dapat mengaktifkan jenis enkripsi ini dengan memperbarui konfigurasi enkripsi default untuk bucket. Kemudian, Anda dapat menggunakan SSE-C dalam permintaan unggahan Anda dengan meneruskan header yang diperlukan. LihatTindakan Amazon S3 yang mendukung penulisan data dengan SSE-C, dan pastikan untuk menyertakanHeader API S3 diperlukan untuk enkripsi objek SSE-C dan permintaan dekripsi.
Saat Anda mengunggah objek yang menentukan SSE-C, 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.
Sebelum menggunakan SSE-C, pastikan Anda telah meninjau. Pertimbangan sebelum menggunakan SSE-C
Amazon S3 tidak menyimpan kunci enkripsi yang Anda sediakan. Sebaliknya, ia menyimpan nilai Kode Autentikasi Pesan Berbasis Hash (HMAC) salted secara acak dari kunci enkripsi untuk memvalidasi permintaan di masa mendatang. Nilai HMAC salted tidak dapat digunakan untuk mendapatkan nilai kunci enkripsi atau untuk mendekripsi konten objek terenkripsi. Artinya, jika Anda kehilangan kunci enkripsi, Anda akan kehilangan objek.
Tindakan SSE-C dan Header yang Diperlukan
Menentukan SSE-C pada S3 yang didukung APIs memerlukan melewati parameter permintaan tertentu.
PutBucketEncryptionAPI di Amazon S3 digunakan untuk mengonfigurasi enkripsi sisi server default untuk bucket. Namun, PutBucketEncryption tidak mendukung pengaktifan SSE-C sebagai metode enkripsi default untuk bucket. SSE-C adalah metode enkripsi tingkat objek tempat Anda memberikan kunci enkripsi ke Amazon S3 dengan setiap permintaan unggahan atau unduhan objek. Amazon S3 menggunakan kunci ini untuk mengenkripsi atau mendekripsi objek selama permintaan dan kemudian membuang kuncinya. Ini berarti SSE-C diaktifkan berdasarkan per-objek, bukan sebagai pengaturan bucket default.
Tindakan Amazon S3 yang mendukung penulisan data dengan SSE-C
Anda dapat meminta enkripsi sisi server dengan kunci yang disediakan pelanggan (SSE-C) saat menulis objek ke bucket tujuan umum dengan menggunakan operasi atau tindakan API berikut:
Header API S3 diperlukan untuk enkripsi objek SSE-C dan permintaan dekripsi
Anda harus menyediakan tiga header API berikut untuk mengenkripsi atau mendekripsi objek dengan SSE-C:
x-amz-server-side-encryption-customer-algorithmGunakan header ini untuk menentukan algoritma enkripsi. Nilai header harus berupa AES256.
x-amz-server-side-encryption-customer-keyGunakan header ini untuk menyediakan kunci enkripsi 256-bit yang disandikan base64 untuk Amazon S3 untuk digunakan untuk mengenkripsi atau mendekripsi data Anda.
x-amz-server-side-encryption-customer-key-MD5Gunakan header ini untuk memberikan MD5 intisari 128-bit yang dikodekan base64 dari kunci enkripsi menurut RFC 1321. Amazon S3 menggunakan header ini untuk pemeriksaan integritas pesan guna memastikan bahwa kunci enkripsi dikirimkan tanpa kesalahan.
Anda harus menyediakan tiga header API berikut untuk menyalin objek sumber yang dienkripsi dengan SSE-C:
x-amz-copy-source-server-side-encryption-customer-algorithmSertakan header ini untuk menentukan algoritme yang harus digunakan Amazon S3 untuk mendekripsi objek sumber. Nilai ini harus berupa AES256.
x-amz-copy-source-server-side-encryption-customer-keySertakan 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-MD5Sertakan header ini untuk memberikan MD5 intisari 128-bit yang dikodekan base64 dari kunci enkripsi menurut RFC 1321.
Contoh kebijakan bucket untuk menegakkan enkripsi SSE-C
Untuk mewajibkan SSE-C untuk semua objek yang ditulis ke bucket Amazon S3, Anda dapat menggunakan kebijakan bucket. Misalnya, kebijakan bucket berikut menolak izin unggah objek (s3:PutObject) untuk semua permintaan yang tidak menyertakan header x-amz-server-side-encryption-customer-algorithm 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"
}
}
}
]
}
Jika Anda menggunakan kebijakan bucket untuk mengharuskan SSE-C aktifs3:PutObject, Anda harus menyertakan x-amz-server-side-encryption-customer-algorithm header di semua permintaan unggahan multibagian (CreateMultipartUpload, UploadPart, dan). CompleteMultipartUpload
Presigned URLs dan SSE-C
Anda dapat membuat URL yang telah ditandatangani sebelumnya yang dapat digunakan untuk operasi seperti mengunggah objek baru, mengambil objek yang sudah ada, atau mengambil metadata objek. URLsDukungan presigned SSE-C sebagai berikut:
-
Saat membuat URL yang telah ditandatangani, Anda harus menentukan algoritma dengan menggunakan header x-amz-server-side-encryption-customer-algorithm dalam perhitungan tanda tangan.
-
Saat menggunakan URL yang ditandatangani sebelumnya untuk mengunggah objek baru, mengambil objek yang sudah ada, atau mengambil metadata objek saja, Anda harus memberikan semua header enkripsi dalam permintaan aplikasi klien.
Untuk non-SSE-C objek, Anda dapat membuat URL yang telah ditetapkan sebelumnya dan langsung menempelkan URL tersebut ke browser untuk mengakses data.
Namun, Anda tidak dapat melakukan ini untuk objek SSE-C, karena selain URL yang ditandatangani sebelumnya, Anda juga harus menyertakan header HTTP yang kustom untuk objek SSE-C. Oleh karena itu, Anda dapat menggunakan presigned URLs untuk objek SSE-C hanya secara terprogram.
Untuk informasi lebih lanjut tentang presigned URLs, lihatUnduh dan unggah objek dengan presigned URLs.
Membuat permintaan dengan SSE-C
Pada saat pembuatan objek dengan API REST, Anda dapat menentukan enkripsi di sisi server dengan kunci yang disediakan pelanggan (SSE-C). Ketika Anda menggunakan SSE-C, Anda harus memberikan informasi kunci enkripsi menggunakan. Header API S3 diperlukan untuk permintaan untuk menyalin objek sumber yang dienkripsi dengan SSE-C Anda dapat menggunakan pustaka pembungkus AWS SDK untuk menambahkan header ini ke permintaan Anda. Jika perlu, Anda dapat melakukan panggilan API REST Amazon S3 secara langsung di aplikasi Anda.
Penggunaan API REST
Amazon S3 REST yang mendukung APIs SSE-C
Amazon S3 berikut APIs mendukung enkripsi sisi server dengan kunci enkripsi yang disediakan pelanggan (SSE-C).
-
GET operation–Saat mengambil objek menggunakan API GET (lihat GET Object), Anda dapat menentukan header permintaan.
-
HEAD operation–Untuk mengambil metadata objek menggunakan API HEAD (lihat HEAD Object), Anda dapat menentukan header permintaan ini.
-
PUT operation–Saat Anda mengunggah data dengan menggunakan API PUT Objek (lihat PUT Objek), Anda dapat menentukan header permintaan ini.
-
Unggahan Multibagian–Saat mengunggah objek yang berukuran besar menggunakan API unggahan multibagian, Anda dapat menentukan header ini. Anda menentukan header ini dalam permintaan inisiat (lihat Memulai Unggahan Multibagian) dan setiap permintaan unggahan bagian berikutnya (lihat Bagian Unggah atau). UploadPartCopy Untuk setiap permintaan unggahan bagian, informasi enkripsi harus sama dengan yang Anda berikan dalam permintaan unggahan multibagian.
-
POST operation–Saat menggunakan POST operation untuk mengunggah objek (lihat Objek POST), alih-alih dengan header permintaan, Anda memberikan informasi yang sama di dalam bidang formulir.
-
Salin operasi — Saat Anda menyalin objek (lihat CopyObject), Anda memiliki objek sumber dan objek target:
Menggunakan AWS SDKs untuk menentukan SSE-C untuk operasi PUT, GET, Head, dan Copy
Contoh berikut ini menunjukkan cara untuk meminta enkripsi di sisi server dengan kunci yang disediakan pelanggan (SSE-C) untuk objek. Contoh melakukan operasi berikut. Setiap operasi menunjukkan cara menentukan SSE-C-related header 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 enkripsinya 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
-
Contoh ini menunjukkan cara untuk mengunggah objek dalam satu operasi. Saat menggunakan API Unggahan Multibagian 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 selengkapnya tentang kelas SSECustomerKey, lihat bagian API REST.
Untuk petunjuk cara membuat dan menguji sampel yang berfungsi, lihat Memulai di Panduan AWS SDK for Java Pengembang.
contoh
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
-
Untuk informasi tentang menyiapkan dan menjalankan contoh kode, lihat Memulai SDK for .NET di AWSAWS SDK for .NET Developer Guide.
contoh
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);
}
}
}
Menggunakan AWS SDKs untuk menentukan SSE-C untuk unggahan multipart
Contoh di bagian sebelumnya menunjukkan cara meminta enkripsi di sisi server dengan kunci yang disediakan pelanggan (SSE-C) dalam operasi PUT, GET, Head, dan Copy. Bagian ini menjelaskan Amazon S3 lain APIs yang mendukung SSE-C.
- Java
-
Untuk mengunggah objek besar, Anda dapat menggunakan unggahan APIs multipart. Untuk informasi selengkapnya, lihat Mengunggah dan menyalin objek menggunakan unggahan multipart di Amazon S3. Anda dapat menggunakan level tinggi atau level rendah APIs untuk mengunggah objek besar. Ini APIs mendukung header terkait enkripsi dalam permintaan.
-
Saat menggunakan TransferManager API tingkat tinggi, Anda menyediakan header khusus enkripsi di. PutObjectRequest Untuk informasi selengkapnya, lihat Pengunggahan objek menggunakan unggahan multibagian.
-
Saat menggunakan API tingkat rendah, Anda memberikan informasi terkait enkripsi pada InitiateMultipartUploadRequest, diikuti dengan informasi enkripsi identik pada setiap UploadPartRequest. Anda tidak perlu memberikan header kustom enkripsi apa pun dalam CompleteMultipartUploadRequest Anda. Sebagai contoh, lihat Menggunakan AWS SDKs (API tingkat rendah).
Contoh berikut menggunakan TransferManager untuk membuat objek dan menunjukkan cara memberikan informasi terkait SSE-C. Contoh ini melakukan hal berikut:
-
Membuat objek menggunakan metode TransferManager.upload(). Dalam PutObjectRequest contoh, Anda memberikan informasi kunci enkripsi dalam permintaan. 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 tersebut sebelum menyalinnya.
contoh
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 API unggahan multibagian (lihatMengunggah dan menyalin objek menggunakan unggahan multipart di Amazon S3). AWS SDK for .NET menyediakan level tinggi atau APIs level rendah untuk mengunggah objek besar. Ini APIs mendukung header terkait enkripsi dalam permintaan.
-
Saat menggunakan API Transfer-Utility tingkat tinggi, Anda menyediakan header kustom enkripsi di TransferUtilityUploadRequest seperti yang ditunjukkan. 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 API tingkat rendah, Anda memberikan informasi terkait enkripsi dalam memulai permintaan unggahan multibagian, diikuti dengan informasi enkripsi yang sama 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 (API tingkat rendah).
Berikut ini adalah contoh pengunggahan multibagian tingkat rendah yang membuat salinan objek besar yang sudah ada. Pada contoh, objek yang akan disalin disimpan di Amazon S3 menggunakan SSE-C, dan Anda ingin menyimpan objek target juga menggunakan SSE-C. Dalam contoh ini, 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.
contoh
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);
}
}
}
}