Utilisation du chiffrement côté serveur avec des clés fournies par le client (-C) SSE - Amazon Simple Storage Service

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation du chiffrement côté serveur avec des clés fournies par le client (-C) SSE

Le chiffrement côté serveur consiste à protéger les données au repos. Un chiffrement côté serveur chiffre uniquement les données d'objet, pas les métadonnées d'objet. En utilisant le chiffrement côté serveur avec des clés fournies par le client (SSE-C), vous pouvez stocker vos données chiffrées avec vos propres clés de chiffrement. Avec la clé de chiffrement que vous fournissez dans la demande, Amazon S3 gère le chiffrement des données quand il écrit sur les disques et le déchiffrement des données quand vous accédez à vos objets. Par conséquent, vous n'avez pas besoin de conserver de code pour procéder au chiffrement et déchiffrement des données. Il ne vous reste qu'à gérer les clés de chiffrement que vous fournissez.

Lorsque vous chargez un objet, Amazon S3 utilise la clé de chiffrement que vous fournissez pour appliquer un chiffrement AES -256 à vos données. Amazon S3 supprime ensuite la clé de chiffrement de la mémoire. Lorsque vous récupérez un objet, vous devez fournir la même clé de chiffrement dans la demande. Amazon S3 vérifie tout d'abord que la clé de chiffrement que vous avez fournie correspond, puis il déchiffre l'objet avant de vous renvoyer les données de ce dernier.

L'utilisation de SSE -C est gratuite. Toutefois, les demandes de configuration et d'utilisation de SSE -C entraînent des frais de demande standard pour Amazon S3. Pour obtenir des informations sur la tarification, consultez Tarification Amazon S3.

Note

Amazon S3 ne stocke pas la clé de chiffrement que vous fournissez. Au lieu de cela, il stocke une valeur de code d'authentification de message basée sur le hachage (HMAC) salée aléatoirement de la clé de chiffrement pour valider les demandes futures. La HMAC valeur salée ne peut pas être utilisée pour dériver la valeur de la clé de chiffrement ou pour déchiffrer le contenu de l'objet chiffré. Cela signifie que si vous perdez la clé de chiffrement, vous perdez l'objet.

S3 Replication prend en charge les objets chiffrés avec SSE -C. Pour plus d'informations sur la réplication d'objets chiffrés, consultezRéplication d'objets chiffrés (SSE-C, SSE -S3, -, SSE -KMS) DSSE KMS.

Pour plus d'informations sur SSE -C, consultez les rubriques suivantes.

SSE-C vue d'ensemble

Cette section fournit une vue d'ensemble de SSE -C. Lorsque vous utilisez SSE -C, tenez compte des considérations suivantes.

  • Vous devez utiliser HTTPS.

    Important

    Amazon S3 rejette toutes les demandes effectuées HTTP lors de l'utilisation de SSE -C. Pour des raisons de sécurité, nous vous recommandons de considérer que toute clé que vous avez envoyée par erreur est HTTP compromise. Écartez la clé et permutez comme il convient.

  • L'étiquette d'entité (ETag) dans la réponse n'est pas le MD5 hachage des données de l'objet.

  • Vous gérez un mappage pour savoir quelle clé de chiffrement a été utilisée pour chiffrer quel objet. Amazon S3 ne stocke pas les clés de chiffrement. Vous devez assurer le suivi pour savoir quelle clé de chiffrement a été fournie pour quel objet.

    • Si votre compartiment prend en charge la gestion des versions, chaque version d'objet que vous chargez à l'aide de cette fonctionnalité peut avoir sa propre clé de chiffrement. Vous devez assurer le suivi pour savoir quelle clé de chiffrement a été utilisée pour quelle version d'objet.

    • Etant donné que vous gérez les clés de chiffrement du côté client, vous gérez toute sauvegarde supplémentaire, comme la rotation des clés, du côté client.

    Avertissement

    Si vous perdez la clé de chiffrement, toute requête GET d'un objet sans clé de chiffrement échoue et vous perdez l'objet.

Exiger et restreindre SSE -C

Pour exiger SSE -C pour tous les objets d'un compartiment Amazon S3 particulier, vous pouvez utiliser une politique de compartiment.

Par exemple, la politique de compartiment suivante refuse les autorisations upload object (s3:PutObject) pour toutes les demandes qui n'incluent pas l'x-amz-server-side-encryption-customer-algorithmen-tête demandant 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" } } } ] }

Vous pouvez également utiliser une politique pour limiter le chiffrement côté serveur de tous les objets figurant dans un compartiment Amazon S3 particulier. Par exemple, la politique de compartiment suivante refuse l'autorisation upload object (s3:PutObject) à tout le monde si la demande inclut l'x-amz-server-side-encryption-customer-algorithmen-tête demandant 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" } } } ] }
Important

Si vous utilisez une politique de compartiment pour exiger l'activation de SSE -Cs3:PutObject, vous devez inclure l'x-amz-server-side-encryption-customer-algorithmen-tête dans toutes les demandes de téléchargement partitionné (CreateMultipartUpload, UploadPart, etCompleteMultipartUpload).

Présigné URLs et -C SSE

Vous pouvez générer un présigné URL qui peut être utilisé pour des opérations telles que le téléchargement d'un nouvel objet, la récupération d'un objet existant ou la récupération des métadonnées d'un objet. URLsSupport pré-signé SSE -C comme suit :

  • Lors de la création d'un présignéURL, vous devez spécifier l'algorithme en utilisant l'x-amz-server-side​-encryption​-customer-algorithmen-tête dans le calcul de la signature.

  • Lorsque vous utilisez le présigné URL pour télécharger un nouvel objet, récupérer un objet existant ou récupérer uniquement les métadonnées d'un objet, vous devez fournir tous les en-têtes de chiffrement dans la demande de votre application cliente.

    Note

    Pour les objets autres que SSE -C, vous pouvez générer un présigné URL et le coller directement URL dans un navigateur pour accéder aux données.

    Toutefois, vous ne pouvez pas le faire pour les objets SSE -C, car en plus des objets présignésURL, vous devez également inclure HTTP des en-têtes spécifiques aux SSE objets -C. Par conséquent, vous ne pouvez utiliser les objets presigned URLs for SSE -C que par programmation.

Pour plus d'informations sur le présignéURLs, consultezTravailler avec Presigned URLs.

Spécification du chiffrement côté serveur à l'aide des clés fournies par le client (-C) SSE

Au moment de la création de l'objet avec le RESTAPI, vous pouvez spécifier le chiffrement côté serveur à l'aide des clés fournies par le client (-C). SSE Lorsque vous utilisez SSE -C, vous devez fournir des informations de clé de chiffrement à l'aide des en-têtes de demande suivants.

Name (Nom) Description
x-amz-server-side​-encryption​-customer-algorithm

Utilisez cet en-tête pour spécifier l'algorithme du chiffrement. La valeur de l'en-tête doit être AES256.

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

Utilisez cet en-tête pour fournir la clé de chiffrement de 256 bits encodée en Base64 qu'Amazon S3 doit utiliser pour chiffrer ou déchiffrer les données.

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

Utilisez cet en-tête pour fournir le MD5 résumé de 128 bits codé en base64 de la clé de chiffrement conformément à la norme 1321. RFC Amazon S3 utilise cet en-tête pour vérifier l'intégrité du message et veiller à ce que la clé de chiffrement ait été transmise sans erreur.

Vous pouvez utiliser les bibliothèques de AWS SDK wrapper pour ajouter ces en-têtes à votre demande. Si nécessaire, vous pouvez passer les REST API appels Amazon S3 directement dans votre application.

Note

Vous ne pouvez pas utiliser la console Amazon S3 pour télécharger un objet et demander SSE -C. Vous ne pouvez pas non plus utiliser la console pour mettre à jour (par exemple, modifier la classe de stockage ou ajouter des métadonnées) un objet existant stocké à l'aide de SSE -C.

Repos Amazon S3 APIs compatible avec SSE -C

Les Amazon S3 suivants prennent en APIs charge le chiffrement côté serveur à l'aide de clés de chiffrement fournies par le client (-C). SSE

  • GETopération — Lorsque vous récupérez des objets à l'aide de GET API (voir GETObject), vous pouvez spécifier les en-têtes de demande.

  • HEADopération — Pour récupérer les métadonnées d'un objet à l'aide de HEAD API (voir HEADObject), vous pouvez spécifier ces en-têtes de demande.

  • PUTopération — Lorsque vous chargez des données à l'aide de l'PUTobjet API (voir PUTObjet), vous pouvez spécifier ces en-têtes de demande.

  • Téléchargement partitionné — Lorsque vous chargez des objets volumineux à l'aide du téléchargement partitionnéAPI, vous pouvez spécifier ces en-têtes. Vous spécifiez ces en-têtes dans la demande initiale (consultez Lancement du chargement partitionné (langue française non garantie)) et dans chaque demande de chargement de partie suivante (consultez Chargement d'une partie ou Chargement d'une partie (Copy) (langue française non garantie)). Pour chaque demande de chargement d'une partie, les informations de chiffrement doivent être les mêmes que celles fournies dans la demande de lancement du chargement partitionné.

  • POSTopération — Lorsque vous utilisez une POST opération pour télécharger un objet (voir POSTObjet), au lieu des en-têtes de demande, vous fournissez les mêmes informations dans les champs du formulaire.

  • Opération de copie — Lorsque vous copiez un objet (voir PUTObjet - Copier), vous disposez à la fois d'un objet source et d'un objet cible :

    • Si vous souhaitez que l'objet cible soit chiffré à l'aide d'un chiffrement côté serveur avec des clés AWS gérées, vous devez fournir l'en-tête de la x-amz-server-side​-encryption demande.

    • Si vous souhaitez que l'objet cible soit chiffré à l'aide de SSE -C, vous devez fournir les informations de chiffrement à l'aide des trois en-têtes décrits dans le tableau précédent.

    • Si l'objet source est chiffré à l'aide de SSE -C, vous devez fournir les informations de clé de chiffrement à l'aide des en-têtes suivants afin qu'Amazon S3 puisse déchiffrer l'objet pour le copier.

      Name (Nom) Description
      x-amz-copy-source​-server-side​-encryption​-customer-algorithm

      Incluez cet en-tête pour spécifier l'algorithme qu'Amazon S3 doit utiliser pour déchiffrer l'objet source. La valeur doit être AES256.

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

      Incluez cet en-tête pour fournir la clé de chiffrement encodée en Base64 qu'Amazon S3 doit utiliser pour déchiffrer l'objet source. La clé de chiffrement doit être celle fournie à Amazon S3 lorsque vous avez créé l'objet source. Sinon, Amazon S3 ne peut pas déchiffrer l'objet.

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

      Incluez cet en-tête pour fournir le MD5 résumé de 128 bits codé en base64 de la clé de chiffrement conformément à la norme 1321. RFC

Les exemples suivants montrent comment demander un chiffrement côté serveur avec des clés fournies par le client (SSE-C) pour des objets. Les exemples exécutent les opérations suivantes. Chaque opération montre comment spécifier les en-têtes SSE liés à -C dans la demande :

  • Put object – Charge un objet et demande un chiffrement côté serveur avec une clé de chiffrement fournie par le client.

  • Get object – Télécharge l'objet chargé à l'étape précédente. Dans la demande, vous fournissez les mêmes informations de chiffrement que celles fournies lors du chargement de l'objet. Amazon S3 a besoin de ces informations pour déchiffrer l'objet afin de pouvoir vous le renvoyer.

  • Get object metadata – Récupère les métadonnées de l'objet. Vous fournissez les mêmes informations de chiffrement que celles utilisées quand l'objet a été chargé.

  • Copy object – Effectue une copie de l'objet précédemment chargé. L'objet source étant stocké à l'aide de SSE -C, vous devez fournir ses informations de chiffrement dans votre demande de copie. Par défaut, Amazon S3 ne chiffre la copie de l'objet que si vous le demandez explicitement. Cet exemple demande à Amazon S3 de stocker une copie chiffrée de l'objet.

Java
Note

Cet exemple montre comment copier un objet en une seule opération. Lorsque vous utilisez le téléchargement partitionné API pour télécharger des objets volumineux, vous fournissez les informations de chiffrement de la même manière que dans cet exemple. Pour des exemples de téléchargements partitionnés utilisant le AWS SDK for Java, voir. Chargement d'un objet à l'aide du chargement partitionné

Pour ajouter les informations de chiffrement requises, vous incluez une clé SSECustomerKey dans votre demande. Pour plus d'informations sur le SSECustomerKey cours, consultez la REST API section.

Pour plus d'informations sur SSE -C, consultezUtilisation du chiffrement côté serveur avec des clés fournies par le client (-C) SSE. Pour obtenir des instructions sur la création et le test d'un échantillon fonctionnel, voir Getting Started dans le guide du AWS SDK for Java développeur.

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
Note

Pour des exemples de chargement d'objets volumineux à l'aide du téléchargement partitionnéAPI, reportez-vous Chargement d'un objet à l'aide du chargement partitionné aux sections et. Utilisation du AWS SDKs (bas niveauAPI)

Pour plus d'informations sur SSE -C, consultezUtilisation du chiffrement côté serveur avec des clés fournies par le client (-C) SSE. Pour plus d'informations sur la configuration et l'exécution des exemples de code, consultez Getting Started with the AWS SDK for. NETdans le AWS SDKfour. NETGuide du développeur.

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'exemple de la section précédente montre comment demander un chiffrement côté serveur avec une clé fournie par le client (SSE-C) dans les opérations PUTGET, Head et Copy. Cette section décrit les autres Amazon S3 APIs qui prennent en charge SSE -C.

Java

Pour télécharger des objets de grande taille, vous pouvez utiliser le téléchargement partitionné API (voirChargement et copie d'objets à l'aide d'un chargement partitionné). Vous pouvez utiliser le haut niveau ou le bas niveau APIs pour télécharger des objets volumineux. Ils APIs prennent en charge les en-têtes liés au chiffrement dans la demande.

  • Lorsque vous utilisez le haut niveau TransferManagerAPI, vous fournissez les en-têtes spécifiques au chiffrement dans le PutObjectRequest (voir). Chargement d'un objet à l'aide du chargement partitionné

  • Lorsque vous utilisez le niveau inférieurAPI, vous fournissez des informations relatives au chiffrement dans leInitiateMultipartUploadRequest, suivies d'informations de chiffrement identiques dans chacun d'entre eux. UploadPartRequest Il est inutile de fournir des en-têtes liés au chiffrement dans votre objet CompleteMultipartUploadRequest. Pour obtenir des exemples, consultez Utilisation du AWS SDKs (bas niveauAPI).

L'exemple suivant permet TransferManager de créer des objets et montre comment fournir des informations relatives à SSE -C. Cet exemple effectue les opérations suivantes :

  • Crée un objet à l'aide de la méthode TransferManager.upload(). Dans l'instance PutObjectRequest, vous fournissez à la demande les informations de clé de chiffrement. Amazon S3 chiffre l'objet en utilisant la clé fournie par le client.

  • Effectue une copie de l'objet en appelant la méthode TransferManager.copy(). L'exemple demande à Amazon S3 de chiffrer la copie de l'objet à l'aide d'un nouvel objet SSECustomerKey. Comme l'objet source est chiffré à l'aide de SSE -C, il fournit CopyObjectRequest également la clé de chiffrement de l'objet source afin qu'Amazon S3 puisse déchiffrer l'objet avant de le copier.

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

Pour télécharger des objets de grande taille, vous pouvez utiliser le téléchargement partitionné API (voirChargement et copie d'objets à l'aide d'un chargement partitionné). AWS SDKpour. NETpermet de télécharger des objets de grande taille à la fois APIs de haut niveau et de bas niveau. Ils APIs prennent en charge les en-têtes liés au chiffrement dans la demande.

  • Lorsque vous utilisez le haut niveau Transfer-Utility API, vous fournissez les en-têtes spécifiques au chiffrement dans leTransferUtilityUploadRequest, comme indiqué. Pour des exemples de code, consultez Chargement d'un objet à l'aide du chargement partitionné.

    TransferUtilityUploadRequest request = new TransferUtilityUploadRequest() { FilePath = filePath, BucketName = existingBucketName, Key = keyName, // Provide encryption information. ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256, ServerSideEncryptionCustomerProvidedKey = base64Key, };
  • Lorsque vous utilisez le bas niveauAPI, vous fournissez des informations relatives au chiffrement dans la demande de lancement de téléchargement en plusieurs parties, puis des informations de chiffrement identiques dans les demandes partielles de téléchargement suivantes. Il est toutefois inutile de fournir des en-têtes liés au chiffrement dans votre demande de fin de chargement partitionné. Pour obtenir des exemples, consultez Utilisation du AWS SDKs (bas niveauAPI).

    L'exemple suivant concerne un chargement partitionné de niveau inférieur exécutant une copie d'un objet volumineux existant. Dans l'exemple, l'objet à copier est stocké dans Amazon S3 à l'aide de SSE -C, et vous souhaitez également enregistrer l'objet cible à l'aide de SSE -C. Dans cet exemple, vous devez effectuer les opérations suivantes :

    • Initier une demande de chargement partitionné en fournissant une clé de chiffrement et les informations connexes.

    • Fournir les clés de chiffrement de l'objet source et cible et les informations relatives dans la CopyPartRequest.

    • Obtenir la taille de l'objet source à copier en récupérant les métadonnées de l'objet.

    • Charger les objets par lots de 5 Mo.

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