Utilisation du chiffrement au niveau du champ pour faciliter la protection des données sensibles - Amazon CloudFront

Utilisation du chiffrement au niveau du champ pour faciliter la protection des données sensibles

Avec Amazon CloudFront, vous pouvez renforcer la sécurité des connexions de bout en bout aux serveurs d’origine à l’aide de HTTPS. Le chiffrement au niveau du champ ajoute une couche de sécurité, qui vous permet de protéger des données spécifiques tout au long du traitement du système, pour que seules certaines applications puissent les voir.

Grâce au chiffrement au niveau du champ, vous pouvez permettre à vos utilisateurs de charger de manière sécurisée des informations sensibles envoyées à vos serveurs web. Les informations sensibles fournies par vos utilisateurs sont chiffrées à la périphérie, à proximité de l’utilisateur, et restent chiffrées tout le long de votre pile d’applications. Ce chiffrement garantit que seules les applications qui ont besoin des données (et qui disposent des informations d’identification pour les déchiffrer) sont en mesure de le faire.

Pour utiliser le chiffrement au niveau du champ, lors de la configuration de votre distribution CloudFront, spécifiez l’ensemble des champs de requêtes POST que vous voulez voir chiffrés et la clé publique à utiliser pour les chiffrer. Vous pouvez chiffrer jusqu’à 10 champs de données dans une requête. (Vous ne pouvez pas chiffrer toutes les données dans une requête avec chiffrement au niveau du champ ; vous devez spécifier des champs individuels à chiffrer).

Lorsque la requête HTTPS avec chiffrement au niveau du champ est réacheminée vers l’origine, et que la requête est acheminée dans votre application ou sous-système d’origine, les données sensibles sont toujours chiffrées, ce qui réduit le risque de violation ou de perte accidentelle des données sensibles. Les composants devant accéder aux données sensibles pour des raisons professionnelles, comme un système de traitement de paiement qui aurait besoin d’accéder à un numéro de crédit, peuvent utiliser la clé privée adéquate pour déchiffrer les données et y accéder.

Note

Pour utiliser le chiffrement au niveau du champ, votre origine doit prendre en charge l’encodage segmenté.

Chiffrement au niveau du champ dans CloudFront

Le chiffrement au niveau du champ de CloudFront utilise le chiffrement asymétrique, également connu sous le nom de chiffrement à clé publique. Vous fournissez une clé publique à CloudFront et toutes les données sensibles que vous spécifiez sont automatiquement chiffrées. La clé que vous fournissez à CloudFront ne peut pas être utilisée pour déchiffrer les valeurs chiffrées. Seule votre clé privée est valide.

Chiffrer uniquement des données sensibles

Présentation du chiffrement au niveau du champ

Les étapes suivantes présentent la configuration de chiffrement au niveau du champ. Pour connaître les étapes spécifiques, consultez Configuration du chiffrement au niveau du champ.

  1. Obtenez une paire de clés publique/clé privée. Vous devez obtenir et ajouter la clé publique avant de commencer à configurer le chiffrement au niveau du champ dans CloudFront.

  2. Créez un profil de chiffrement au niveau du champs. Les profils de chiffrement au niveau du champ, que vous créez dans CloudFront, définissent les champs que vous souhaitez voir chiffrés.

  3. Créez une configuration de chiffrement au niveau du champ. Une configuration spécifie les profils à utiliser selon le type de contenu de la requête ou un argument de requête pour chiffrer des champs de données spécifiques. Vous pouvez également choisir les options de comportement de transfert de demande que vous souhaitées pour différents scénarios. Par exemple, vous pouvez définir le comportement lorsque le nom de profil spécifié par l’argument dans une URL de demande n’existe pas dans CloudFront.

  4. Lien vers un comportement de cache. Associez la configuration à un comportement de cache pour une distribution afin de spécifier quand CloudFront doit chiffrer les données.

Configuration du chiffrement au niveau du champ

Suivez ces étapes pour commencer à utiliser le chiffrement au niveau du champ. Pour en savoir plus sur les quotas (auparavant appelés limites) liés au chiffrement au niveau du champ, consultez Quotas.

Étape 1 : créer une paire de clés RSA

Pour commencer, vous devez créer une paire de clés RSA qui inclut une clé publique et une clé privée. La clé publique permet à CloudFront de chiffrer les données, tandis que la clé privée permet aux composants au niveau de votre origine de déchiffrer les champs qui ont été chiffrés. Vous pouvez utiliser OpenSSL ou un autre outil pour créer une paire de clés. La taille de la clé doit être de 2 048 bits.

Par exemple, si vous utilisez OpenSSL, vous pouvez exécuter la commande suivante pour générer une paire de clés avec une longueur de 2048 bits et l’enregistrer dans le fichier private_key.pem:

openssl genrsa -out private_key.pem 2048

Le fichier obtenu contient à la fois la clé publique et la clé privée. Pour extraire la clé publique de ce fichier, exécutez la commande suivante :

openssl rsa -pubout -in private_key.pem -out public_key.pem

Le fichier de clé publique (public_key.pem) contient la valeur de clé codée que vous collez à l’étape suivante.

Étape 2 : ajouter la clé publique à CloudFront

Après avoir obtenu votre paire de clés RSA, ajoutez votre clé publique à CloudFront.

Pour ajouter votre clé publique à CloudFront (console)
  1. Connectez-vous à AWS Management Console et ouvrez la console CloudFront à l’adresse https://console.aws.amazon.com/cloudfront/v4/home.

  2. Dans le volet de navigation, sélectionnez Clé publique.

  3. Choisissez Ajouter une clé publique.

  4. Dans Nom de clé, tapez un nom unique pour la clé. Le nom ne peut pas contenir d’espaces et ne peut contenir que des caractères alphanumériques, des traits de soulignement (_) et des tirets (-). Le nombre maximum de caractères est 128.

  5. Pour Key value (Valeur de clé), collez la valeur de clé encodée pour votre clé publique, y compris les lignes -----BEGIN PUBLIC KEY----- et -----END PUBLIC KEY-----.

  6. Pour Commentaire, ajoutez un commentaire facultatif. Par exemple, vous pouvez inclure la date d’expiration pour la clé publique.

  7. Choisissez Add (Ajouter).

Pour ajouter d’autres clés à utiliser avec CloudFront, répétez cette procédure.

Étape 3 : créer un profil de chiffrement au niveau du champ

Après avoir ajouté au moins une clé publique à CloudFront, créez un profil indiquant à CloudFront les champs à chiffrer.

Créer un profil de chiffrement au niveau du champ (console)
  1. Dans le volet de navigation, sélectionnez Chiffrement au niveau du champ.

  2. Choisissez Créer un profil.

  3. Remplissez les champs suivants :

    Profile name (Nom du profil)

    Saisissez un nom unique pour le profil. Le nom ne peut pas contenir d’espaces et ne peut contenir que des caractères alphanumériques, des traits de soulignement (_) et des tirets (-). Le nombre maximum de caractères est 128.

    Nom de clé publique

    Dans la liste déroulante, sélectionnez le nom d’une clé publique que vous avez ajoutée à CloudFront à l’étape 2. CloudFront utilise la clé pour chiffrer les champs que vous spécifiez dans ce profil.

    Nom du fournisseur

    Saisissez une phrase facilitant l’identification de la clé, comme le fournisseur de la paire de clés. Ces informations, tout comme la clé privée, sont nécessaires lors du déchiffrement des champs de données par les applications. Le nom du fournisseur ne peut pas contenir d’espaces et ne peut contenir que des caractères alphanumériques, des deux-points (:), des traits de soulignement (_) et des tirets (-). Le nombre maximum de caractères est 128.

    Modèle de nom de champ

    Saisissez les noms des champs de données, ou des modèles identifiant des noms de champs de données dans la requête, que vous voulez que CloudFront chiffre. Sélectionnez l’option + pour ajouter tous les champs que vous souhaitez chiffrer avec cette clé.

    Pour le modèle de nom de champ, vous pouvez saisir le nom entier du champ de données, comme DateOfBirth ou seulement la première partie du nom avec un caractère générique (*), comme CreditCard*. Le modèle de champ de nom ne peut contenir que des caractères alphanumériques, des crochets ([ et ]), des points (.), des traits de soulignement (_) et des tirets (-) et en option, le métacaractère (*).

    N’utilisez pas de caractères qui se chevauchent pour différents modèles de nom de champ. Par exemple, si vous avez un modèle de nom de champ ABC*, vous ne pouvez pas ajouter un autre modèle de nom de champ AB*. De plus, les noms de champ sont sensibles à la casse et le nombre maximum de caractères ne doit pas dépasser 128.

    Commentaire

    (Facultatif) Saisissez un commentaire sur ce profil. Le nombre maximum de caractères à utiliser est de 128.

  4. Une fois les champs remplis, choisissez Créer un profil.

  5. Pour ajouter d’autres profils, Sélectionnez Ajouter un profil.

Étape 4 : créer une configuration

Après avoir créé un ou plusieurs profils de chiffrement au niveau du champ, créez une configuration spécifiant le type de contenu de la requête incluant les données à chiffrer, le profil à utiliser pour le chiffrement et d’autres options indiquant la manière dont vous voulez que CloudFront gère le chiffrement.

Par exemple, lorsque CloudFront ne parvient pas à chiffrer les données, vous pouvez spécifier s’il doit bloquer ou réacheminer une requête vers votre origine dans les cas suivants :

  • Lorsque le type de contenu d’une demande n’est pas dans une configuration : si vous n’avez pas déterminé le type de contenu d’une configuration, vous pouvez spécifier si CloudFront doit réacheminer la requête avec ce type de contenu vers l’origine, sans chiffrer les champs de données, ou bloquer la requête et renvoyer une erreur.

    Note

    Si vous ajoutez un type de contenu à une configuration mais que vous n’avez pas spécifié de profil à utiliser avec ce type, CloudFront réachemine toujours les requêtes avec ce type de contenu vers l’origine.

  • Lorsque le nom de profil fourni dans un argument de requête est inconnu : lorsque vous spécifiez l’argument de requête fle-profile avec un nom de profil qui n’existe pas pour votre distribution, vous pouvez spécifier si CloudFront doit renvoyer la requête à l’origine sans chiffrer les champs de données, ou bloquer la requête et renvoyer une erreur.

Dans une configuration, vous pouvez également spécifier si fournir un profil en tant qu’argument de requête dans une URL substitue un profil que vous avez mappé vers le type de contenu de cette requête. Par défaut, CloudFront utilise le profil que vous avez mappé à un type de contenu, si vous en spécifiez un. Cela vous permet d’avoir un profil utilisé par défaut, mais de décider, pour certaines requêtes, d’appliquer un autre profil.

Donc, par exemple, vous pouvez spécifier (dans votre configuration) SampleProfile comme profil d’argument de requête à utiliser. Vous pouvez ensuite utiliser l’URL https://d1234.cloudfront.net?fle-profile=SampleProfile au lieu de https://d1234.cloudfront.net, pour que CloudFront utilise SampleProfile pour cette demande, au lieu du profil que vous avez configuré pour le type de contenu de la requête.

Vous pouvez créer jusqu’à 10 configurations pour un seul compte, puis associer l’une des configurations au comportement de cache d’une distribution pour le compte.

Créer une configuration de chiffrement au niveau du champ (console)
  1. Sur la page Chiffrement au niveau du champ, sélectionnez Créer la configuration.

    Remarque : Si vous n’avez pas créé de profil, vous ne verrez pas l’option permettant de créer une configuration.

  2. Renseignez les champs suivants pour spécifier le profil à utiliser. (Certains champs ne peuvent être modifiés).

    Type de contenu (non modifiable)

    Le type de contenu est défini comme application/x-www-form-urlencoded et ne peut être modifié.

    ID de profil par défaut (facultatif)

    Dans la liste déroulante, sélectionnez le profil que vous souhaitez mapper au type de contenu dans le champ Type de contenu.

    Format de contenu (non modifiable)

    Le format du contenu est défini comme URLencoded et ne peut être modifié.

  3. Pour modifier le comportement par défaut de CloudFront pour les options suivantes, sélectionnez la case à cocher appropriée.

    Réacheminer une requête vers l’origine lorsque le type de contenu de a requête n’est pas configuré

    Sélectionnez la case à cocher pour permettre à la requête d’atteindre votre origine si vous n’avez pas spécifié de profil à utiliser pour le type de contenu de la requête.

    Substituer le profil d’un type de contenu avec un argument de requête fourni

    Sélectionnez la case à cocher pour autoriser un profil fourni dans un argument de requête à substituer le profil que vous avez spécifié pour un type de contenu.

  4. Si vous sélectionnez la case à cocher pour autoriser un argument de requête à remplacer le profil par défaut, vous devez renseigner les champs supplémentaires suivants pour la configuration. Vous pouvez créer jusqu’à cinq de ces mappages d’argument de requête à utiliser avec les requêtes.

    Argument de requête

    Saisissez la valeur que vous voulez inclure dans l’URL pour l’argument de requête de fle-profile. Cette valeur indique à CloudFront d’utiliser l’ID de profil (que vous indiquez dans le champ suivant) associée à cet argument de requête de chiffrement au niveau du champ pour cette requête.

    Le nombre maximum de caractères à utiliser est de 128. La valeur ne doit pas contenir d’espaces et ne comporter que des caractères alphanumériques ou les caractères suivants : tiret (-), point (.), trait de soulignement (_), astérisque (*), signe plus (+), pourcentage (%).

    ID de profil

    Dans la liste déroulante, sélectionnez le profil à associer à la valeur que vous avez saisie pour Argument de requête.

    Réacheminer une requête vers l’origine lorsque le profil spécifié dans un argument de requête n’existe pas

    Sélectionnez la case à cocher pour permettre à la demande d’être acheminée vers votre origine si le profil spécifié dans un argument de requête n’est pas défini dans CloudFront.

Étape 5 : ajouter une configuration à un comportement de cache

Pour utiliser le chiffrement au niveau du champ, associez une configuration à un comportement de cache pour une distribution en ajoutant l’ID de configuration en tant que valeur pour votre distribution.

Important

Pour associer une configuration de chiffrement au niveau du champ à un comportement de cache, la distribution doit être configurée pour toujours utiliser HTTPS et accepter des demandes HTTP POST et PUT des utilisateurs. Ainsi, les conditions suivantes doivent être vraies :

  • La Viewer Protocol Policy (Politique de protocole d’utilisateur) du comportement de cache doit être définie sur Redirect HTTP vers HTTPS (Rediriger HTTP vers HTTPS) ou HTTPS Only (HTTPS uniquement). (Dans CloudFormation ou l’API CloudFront, ViewerProtocolPolicy doit être défini sur redirect-to-https ou https-only.)

  • Les Allowed HTTP Methods (Méthodes HTTP autorisées) du comportement du cache doivent être définies sur GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. (Dans CloudFormationou l’API CloudFront AllowedMethods doit être défini sur GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. Ces valeurs peuvent être spécifiées dans n’importe quel ordre).

  • La Stratégie de protocole d’origine du paramètre d’origine doit être définie sur Identique à l’utilisateur ou HTTPS uniquement. (Dans CloudFormation ou l’API CloudFront, OriginProtocolPolicy doit être défini sur match-viewer ou https-only.)

Pour plus d’informations, consultez Référence de tous les paramètres de distribution.

Déchiffrage de champs de données à votre origine

CloudFront chiffre les champs de données à l’aide du AWS Encryption SDK. Les données restent chiffrées dans l’ensemble de votre pile d’applications et ne sont accessibles qu’aux applications possédant les informations d’identification pour les déchiffrer.

Après le chiffrement, le texte chiffré est encodé en base64. Lorsque vos applications déchiffrent le texte à l’origine, elles doivent d’abord décoder le texte chiffré, puis utiliser le kit SDK de chiffrement AWS pour déchiffrer les données.

L’exemple de code suivant illustre la façon dont les applications peuvent déchiffrer des données à votre origine. Remarques :

  • Pour simplifier l’exemple, cet exemple charge des clés publiques et privées (au format DER) à partir de fichiers du répertoire de travail. En pratique, vous devez stocker la clé privée à un emplacement sécurisé hors ligne, par exemple un module de sécurité matérielle hors ligne, et distribuer la clé publique à votre équipe de développement.

  • CloudFront utilise des informations spécifiques lors du chiffrement des données, et le même ensemble de paramètres doit être utilisé au niveau de l’origine pour les déchiffrer. Voici certains paramètres utilisés par CloudFront lors de l’initialisation du MasterKey :

    • PROVIDER_NAME : Vous avez indiqué cette valeur lors de la création d’un profil de chiffrement au niveau du profil. Utilisez la même valeur ici.

    • KEY_NAME : vous avez créé un nom pour votre clé publique lorsque vous l’avez chargée dans CloudFront, puis avez indiqué le nom de clé dans le profil. Utilisez la même valeur ici.

    • ALGORITHME : CloudFront utilise RSA/ECB/OAEPWithSHA-256AndMGF1Padding comme algorithme de chiffrement. Vous devez donc utiliser le même algorithme pour déchiffrer les données.

  • Si vous exécutez l’exemple de programme suivant avec le texte chiffré en tant qu’entrée, les données déchiffrées constituent une sortie de votre console. Pour plus d’informations, consultez l’exemple de code Java dans le kit SDK de chiffrement AWS.

Exemple de code

import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.apache.commons.codec.binary.Base64; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CryptoResult; import com.amazonaws.encryptionsdk.jce.JceMasterKey; /** * Sample example of decrypting data that has been encrypted by CloudFront field-level encryption. */ public class DecryptExample { private static final String PRIVATE_KEY_FILENAME = "private_key.der"; private static final String PUBLIC_KEY_FILENAME = "public_key.der"; private static PublicKey publicKey; private static PrivateKey privateKey; // CloudFront uses the following values to encrypt data, and your origin must use same values to decrypt it. // In your own code, for PROVIDER_NAME, use the provider name that you specified when you created your field-level // encryption profile. This sample uses 'DEMO' for the value. private static final String PROVIDER_NAME = "DEMO"; // In your own code, use the key name that you specified when you added your public key to CloudFront. This sample // uses 'DEMOKEY' for the key name. private static final String KEY_NAME = "DEMOKEY"; // CloudFront uses this algorithm when encrypting data. private static final String ALGORITHM = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; public static void main(final String[] args) throws Exception { final String dataToDecrypt = args[0]; // This sample uses files to get public and private keys. // In practice, you should distribute the public key and save the private key in secure storage. populateKeyPair(); System.out.println(decrypt(debase64(dataToDecrypt))); } private static String decrypt(final byte[] bytesToDecrypt) throws Exception { // You can decrypt the stream only by using the private key. // 1. Instantiate the SDK final AwsCrypto crypto = new AwsCrypto(); // 2. Instantiate a JCE master key final JceMasterKey masterKey = JceMasterKey.getInstance( publicKey, privateKey, PROVIDER_NAME, KEY_NAME, ALGORITHM); // 3. Decrypt the data final CryptoResult <byte[], ? > result = crypto.decryptData(masterKey, bytesToDecrypt); return new String(result.getResult()); } // Function to decode base64 cipher text. private static byte[] debase64(final String value) { return Base64.decodeBase64(value.getBytes()); } private static void populateKeyPair() throws Exception { final byte[] PublicKeyBytes = Files.readAllBytes(Paths.get(PUBLIC_KEY_FILENAME)); final byte[] privateKeyBytes = Files.readAllBytes(Paths.get(PRIVATE_KEY_FILENAME)); publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(PublicKeyBytes)); privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); } }