Utilizzo della crittografia lato server con chiavi fornite dal cliente (SSE-C) - Amazon Simple Storage Service

Utilizzo della crittografia lato server con chiavi fornite dal cliente (SSE-C)

La crittografia lato server consente di proteggere i dati inattivi. La crittografia lato server viene applicata solo ai dati dell'oggetto, non dei metadati dell'oggetto. L'impiego della crittografia lato server con chiavi di crittografia fornite dal cliente (SSE-C) consente di archiviare chiavi di crittografia personalizzate. Con la chiave di crittografia fornita come parte della richiesta, Amazon S3 gestisce la crittografia dei dati durante le operazioni di scrittura su disco e decrittografia dei dati quando viene eseguito l'accesso agli oggetti. Pertanto, non è necessario mantenere alcun codice per effettuare la crittografia e la decrittografia dei dati. L'unica cosa che rimane da fare è gestire le chiavi di crittografia fornite.

Quando viene caricato un oggetto, Amazon S3 utilizza la chiave di crittografia fornita per applicare la crittografia AES-256 ai dati. Amazon S3 rimuove quindi la chiave di crittografia dalla memoria. Quando viene recuperato un oggetto, è necessario fornire la stessa chiave di crittografia come parte della richiesta. Amazon S3 verifica prima che la chiave di crittografia fornita corrisponda, quindi esegue la decrittografia dell'oggetto prima di restituire i relativi dati.

Questa caratteristica non comporta costi supplementari per l'utilizzo di SSE-C. Tuttavia, le richieste di configurazione e utilizzo di SSE-C sono soggette alle tariffe standard delle richieste Amazon S3. Per informazioni sui prezzi, consulta Prezzi di Amazon S3.

Nota

Amazon S3 non archivia le chiavi di crittografia fornite. Archivia invece un valore per il codice di autenticazione dei messaggi basato su hash (HMAC) con salting casuale della chiave di crittografia per convalidare le richieste future. Il valore HMAC con l'introduzione di un sale non può essere utilizzato per derivare il valore della chiave di crittografia o per decrittografare i contenuti dell'oggetto crittografato. Ciò significa che se si perde la chiave di crittografia, si perde l'oggetto.

S3 Replication supporta gli oggetti crittografati con SSE-C. Per ulteriori informazioni sulla replica di oggetti crittografati, consulta Replica di oggetti creati con crittografia lato server (SSE-C, SSE-S3, SSE-KMS).

Per ulteriori informazioni su SSE-C, consulta i seguenti argomenti.

Panoramica di SSE-C

In questa sezione viene fornita una panoramica di SSE-C. Quando si utilizza SSE-C, è necessario tenere presente le considerazioni riportate di seguito.

  • È necessario utilizzare HTTPS.

    Importante

    Amazon S3 rifiuta qualsiasi richiesta effettuata su HTTP quando si utilizza SSE-C. Per motivi di sicurezza, è consigliabile considerare compromessa qualsiasi chiave inviata per errore tramite HTTP. Elimina la chiave ed esegui la rotazione come opportuno.

  • Il tag di entità (ETag) nella risposta non è l'hash MD5 dei dati degli oggetti.

  • L'utente gestisce una mappatura per tenere traccia della chiave di crittografia che è stata utilizzata per crittografare un determinato oggetto. Amazon S3 non archivia le chiavi di crittografia. L'utente è responsabile della tracciatura di ciascuna chiave di crittografia fornita per ogni determinato oggetto.

    • Se per il bucket in uso è abilitata la funzione di controllo delle versioni, ogni versione di oggetto caricata utilizzando questa caratteristica può avere la propria chiave di crittografia. L'utente è responsabile della tracciatura di ciascuna chiave di crittografia utilizzata per ogni determinato oggetto.

    • Dato che l'utente gestisce le chiavi di crittografia lato cliente, gestisce anche eventuali tutele aggiuntive, come la rotazione delle chiavi, lato cliente.

    avvertimento

    Se la chiave di crittografia viene smarrita, qualsiasi richiesta GET di un determinato oggetto senza la rispettiva chiave di crittografia non va a buon fine e l'oggetto viene perduto.

Richiesta e limitazione di SSE-C

Per richiedere le chiavi SSE-C per tutti gli oggetti in uno specifico bucket Amazon S3, è possibile utilizzare una policy di bucket.

Ad esempio, la seguente policy del bucket rifiuta l'autorizzazione per il caricamento di oggetti (s3:PutObject) per tutte le richieste che non includono l'intestazione x-amz-server-side-encryption-customer-algorithm che richiede di SSE-C.

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

Per limitare la crittografia lato server di tutti gli oggetti in uno specifico bucket Amazon S3, è anche possibile utilizzare una policy. Ad esempio, la seguente policy di bucket rifiuta a chiunque l'autorizzazione al caricamento dell'oggetto (s3:PutObject) se la richiesta non include l'intestazione x-amz-server-side-encryption-customer-algorithm che richiede la crittografia con chiavi SSE-C.

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

URL prefirmati e SSE-C

È possibile generare un URL prefirmato che possa essere utilizzato per operazioni quali il caricamento di un nuovo oggetto, il recupero di un oggetto esistente o dei metadata di un oggetto. Gli URL prefirmati supportano le chiavi SSE-C come segue:

  • Quando viene creato un URL prefirmato, è necessario specificare l'algoritmo utilizzando l'intestazione x-amz-server-side​-encryption​-customer-algorithm nel calcolo della firma.

  • Quando viene utilizzato l'URL prefirmato per il caricamento di un nuovo oggetto, il recupero di un oggetto esistente o solo dei metadata di un oggetto, è necessario fornire tutte le intestazioni di crittografia nella richiesta dell'applicazione client.

    Nota

    Per gli oggetti non SSE-C, puoi generare un URL prefirmato e copiarlo direttamente nel browser per accedere ai dati.

    Tuttavia, ciò non è possibile per gli oggetti SSE-C poiché oltre all'URL prefirmato, è anche necessario includere le intestazioni HTTP specifiche degli oggetti SSE-C. È quindi possibile utilizzare URL prefirmati per gli oggetti SSE-C solo a livello di programmazione.

Per ulteriori informazioni sugli URL prefirmati, consulta Utilizzo di URL prefirmati.

Specifica della crittografia lato server con chiavi fornite dal cliente (SSE-C)

Al momento della creazione di oggetti con REST API, è possibile specificare la crittografia lato server con le chiavi fornite dal cliente (SSE-C). Quando si utilizza SSE-C, è necessario fornire le informazioni sulla chiave di crittografia utilizzando le intestazioni di richiesta seguenti.

Nome Descrizione
x-amz-server-side​-encryption​-customer-algorithm

Utilizzare questa intestazione per specificare l'algoritmo di crittografia. Il valore dell'intestazione deve essere AES256.

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

Utilizzare questa intestazione per fornire la chiave di crittografia a 256 bit codificata con base64 per consentire ad Amazon S3 di crittografare o decrittare i dati.

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

Utilizzare questa intestazione per fornire il digest MD5 a 128 bit codificato con base64 della chiave di crittografia secondo RFC 1321. Amazon S3 utilizza questa intestazione per il controllo dell'integrità del messaggio per accertarsi che la chiave di crittografia sia stata trasmessa senza errori.

È possibile utilizzare le librerie wrapper dell'SDK AWS per aggiungere queste intestazioni alla richiesta. Se necessario, è possibile anche effettuare le chiamate REST API di Amazon S3 direttamente nell'applicazione.

Nota

Non è inoltre possibile utilizzare la console Amazon S3 per aggiornare (ad esempio, cambiare la classe di archiviazione o aggiungere metadati) un oggetto archiviato esistente utilizzando la crittografia SSE-C.

REST API di Amazon S3 che supportano SSE-C

Le seguenti API Amazon S3 supportano la crittografia lato server con le chiavi di crittografia fornite dal cliente (SSE-C).

  • Operazione GET: quando si recuperano oggetti utilizzando l'API GET (consulta l'argomento relativo all'operazione GetObject), è possibile specificare le intestazioni di richiesta.

  • Operazione HEAD: per recuperare i metadati dell'oggetto utilizzando l'API HEAD (consulta l'argomento relativo all'operazione HeadObject), è possibile specificare queste intestazioni di richiesta.

  • Operazione PUT: quando si caricano dati utilizzando l'API PUT (consulta l'argomento relativo all'operazione PutObject), è possibile specificare queste intestazioni di richiesta.

  • Caricamento in più parti: quando si caricano oggetti di grandi dimensioni utilizzando l'API per il caricamento in più parti, è possibile specificare queste intestazioni. È necessario specificare queste intestazioni nella richiesta di avvio (consulta l'argomento relativo all'avvio di caricamenti in più parti) e in ogni richiesta di caricamento di parti successive (consulta l'argomento relativo al caricamento delle parti o caricamento delle copie di parti). Per ogni richiesta di caricamento di parte, le informazioni della crittografia devono essere uguali a quelle specificate nella richiesta di avvio di caricamento in più parti.

  • Operazione POST: quando si utilizza un'operazione POST per caricare un oggetto (consulta l'argomento relativo all'oggetto POST), anziché nelle intestazioni di richiesta, è necessario specificare le stesse informazioni nei campi del modulo.

  • Operazione COPY: l'operazione di copia di un oggetto (consulta l'argomento relativo all'operazione CopyObject) interessa un oggetto di origine e un oggetto di destinazione.

    • Se si vuole crittografare l'oggetto di destinazione utilizzando la crittografia lato server con le chiavi gestite da AWS, è necessario fornire l'intestazione di richiesta x-amz-server-side​-encryption.

    • Se si vuole crittografare l'oggetto di destinazione utilizzando SSE-C, è necessario fornire le informazioni della crittografia utilizzando le tre intestazioni descritte nella tabella precedente.

    • Se l'oggetto di origine è crittografato con SSE-C, è necessario fornire le informazioni relative alle chiavi di crittografia utilizzando le seguenti intestazioni affinché Amazon S3 possa decrittare l'oggetto per copiarlo.

      Nome Descrizione
      x-amz-copy-source​-server-side​-encryption​-customer-algorithm

      Includere questa intestazione per specificare l'algoritmo che dovrebbe utilizzare Amazon S3 per decrittare l'oggetto di origine. Questo valore deve essere AES256.

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

      Includere questa intestazione per fornire la chiave di crittografia codificata con base64 per consentire ad Amazon S3 di decrittare l'oggetto di origine. Questa chiave di crittografia deve essere quella fornita ad Amazon S3 quando è stato creato l'oggetto di origine. In caso contrario, Amazon S3 non riesce a decrittare l'oggetto.

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

      Includere questa intestazione per fornire il digest MD5 a 128 bit codificato con base64 della chiave di crittografia secondo RFC 1321.

Nel seguente esempio viene mostrato come richiedere la crittografia lato server con chiavi fornite dal cliente (SSE-C) per gli oggetti. Negli esempi vengono eseguite le operazioni riportate di seguito. Per ogni operazione viene illustrato come specificare le intestazioni correlate alle chiavi SSE-C nella richiesta:

  • Put object: consente di caricare un oggetto e richiedere la crittografia lato server utilizzando la chiave di crittografia fornita dal cliente.

  • Get object: consente di scaricare l'oggetto caricato durante la fase precedente. Nella richiesta, vengono fornite le stesse informazioni di crittografia specificate quando è stato caricato l'oggetto. per consentire ad Amazon S3 di decrittare l'oggetto e di restituirlo.

  • Get object metadata: consente di recuperare i metadati dell'oggetto. Fornire le stesse informazioni di crittografia utilizzate quando l'oggetto è stato creato.

  • Copy object: consente di creare una copia dell'oggetto caricato in precedenza. Poiché l'oggetto di origine è stato archiviato utilizzando la chiave SSE-C, è necessario fornire le relative informazioni di crittografia nella richiesta di copia. Per impostazione predefinita, Amazon S3 esegue la crittografia dell'oggetto solo se richiesta esplicitamente. In questo esempio, Amazon S3 viene configurato per archiviare una copia crittografata dell'oggetto.

Java
Nota

In questo esempio viene illustrato come caricare un oggetto in un'unica operazione. Quando si utilizza l'API per il caricamento in più parti per caricare oggetti di grandi dimensioni, fornire le informazioni di crittografia nello stesso modo mostrato in questo esempio. Per esempi di caricamenti in più parti che utilizzano AWS SDK for Java, consulta Caricamento di un oggetto utilizzando il caricamento in più parti.

Per aggiungere le informazioni di crittografia richieste, includere SSECustomerKey nella richiesta. Per ulteriori informazioni sulla classe SSECustomerKey, consulta la sezione relativa a REST API.

Per informazioni su SSE-C, consulta Utilizzo della crittografia lato server con chiavi fornite dal cliente (SSE-C). Per istruzioni su come creare e testare un esempio di utilizzo, consulta Test degli esempi di codice Java di Amazon S3.

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
Nota

Per esempi di caricamento di oggetti di grandi dimensioni utilizzando l'API per il caricamento in più parti, consulta Caricamento di un oggetto utilizzando il caricamento in più parti e Utilizzo degli SDK AWS (API di basso livello).

Per informazioni su SSE-C, consulta Utilizzo della crittografia lato server con chiavi fornite dal cliente (SSE-C). Per informazioni su come creare e testare un esempio di utilizzo, consulta Esecuzione degli esempi di codice .NET di Amazon S3.

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); } } }

L'esempio nella sezione precedente mostra come richiedere la crittografia lato server con la chiave fornita dal cliente (SSE-C) nelle operazioni PUT, GET, Head e Copy. In questa sezione vengono descritte altre API Amazon S3 che supportano la chiave SSE-C.

Java

Per caricare oggetti di grandi dimensioni, è possibile utilizzare l'API per il caricamento in più parti (consulta Caricamento e copia di oggetti utilizzando il caricamento in più parti). È possibile utilizzare indifferentemente API di livello alto o basso per caricare gli oggetti di grandi dimensioni. Queste API supportano l'uso di intestazioni correlate alla crittografia nella richiesta.

  • Quando si utilizza l'API TransferManager di alto livello, è necessario fornire le intestazioni specifiche della crittografia in PutObjectRequest (consulta Caricamento di un oggetto utilizzando il caricamento in più parti).

  • Quando si utilizza l'API di basso livello, è necessario fornire informazioni correlate alla crittografia nella InitiateMultipartUploadRequest, seguite da informazioni di crittografia identiche in ogni UploadPartRequest. Non è necessario fornire alcuna intestazione specifica della crittografia nella CompleteMultipartUploadRequest. Per alcuni esempi, consulta Utilizzo degli SDK AWS (API di basso livello).

Nel seguente esempio viene utilizzato TransferManager per creare gli oggetti e viene illustrato come fornire le informazioni correlate alla chiave SSE-C. Inoltre, vengono effettuate le seguenti operazioni:

  • Viene creato un oggetto utilizzando il metodo TransferManager.upload(). Nell'istanza PutObjectRequest, fornire le informazioni sulla chiave di crittografia da richiedere. Amazon S3 esegue la crittografia dell'oggetto utilizzando la chiave fornita dal cliente.

  • Viene eseguita una copia dell'oggetto richiamando il metodo TransferManager.copy(). Nell'esempio Amazon S3 viene configurato per crittografare la copia dell'oggetto utilizzando una nuova SSECustomerKey. Poiché l'oggetto di origine è crittografato tramite la chiave SSE-C, CopyObjectRequest fornisce anche la chiave di crittografia dell'oggetto di origine in modo che Amazon S3 possa decrittare l'oggetto prima di copiarlo.

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

Per caricare oggetti di grandi dimensioni, puoi utilizzare l'API per il caricamento in più parti (consulta Caricamento e copia di oggetti utilizzando il caricamento in più parti). AWS SDK per .NET fornisce API di livello alto o basso per caricare gli oggetti di grandi dimensioni. Queste API supportano l'uso di intestazioni correlate alla crittografia nella richiesta.

  • Quando si utilizza l'API Transfer-Utility di alto livello, è necessario fornire le intestazioni specifiche della crittografia in TransferUtilityUploadRequest come mostrato. Per alcuni esempi di codice, consulta Caricamento di un oggetto utilizzando il caricamento in più parti.

    TransferUtilityUploadRequest request = new TransferUtilityUploadRequest() { FilePath = filePath, BucketName = existingBucketName, Key = keyName, // Provide encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, };
  • Quando si utilizza l'API di basso livello, è necessario fornire informazioni correlate alla crittografia nella richiesta di avvio del caricamento in più parti, seguite da informazioni di crittografia identiche nelle successive richieste di caricamento della parte. Non è necessario fornire alcuna intestazione specifica della crittografia nella richiesta di caricamento in più parti completa. Per alcuni esempi, consulta Utilizzo degli SDK AWS (API di basso livello).

    Di seguito è riportato un esempio di caricamento in più parti di basso livello in cui viene creata una copia di un oggetto di grandi dimensioni esistente. Nell'esempio l'oggetto da copiare è archiviato in Amazon S3 con la chiave SSE-C e l'oggetto di destinazione deve essere salvato utilizzando la stessa chiave. Nell'esempio vengono effettuate le seguenti operazioni:

    • Viene avviata una richiesta di caricamento in più parti specificando una chiave di crittografia e informazioni correlate.

    • Vengono fornite chiavi di crittografia e informazioni correlate per gli oggetti di origine e di destinazione nella richiesta CopyPartRequest.

    • Viene ottenuta la dimensione dell'oggetto di origine da copiare recuperando i metadata dell'oggetto.

    • Caricamento degli oggetti in parti da 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); } } } }