Partager via


Utiliser le chiffrement côté client avec Always Encrypted pour Azure Cosmos DB

S’APPLIQUE À : NoSQL

Important

Un changement cassant a été introduit dans la version 1.0 de nos packages de chiffrement. Si vous avez créé des clés de chiffrement de données et des conteneurs prenant en charge le chiffrement avec des versions antérieures, vous devrez recréer vos bases de données et vos conteneurs après migration de votre code client vers des packages 1.0.

Always Encrypted est une fonctionnalité conçue pour protéger les données sensibles, telles que les numéros de carte de crédit ou les numéros nationaux/régionaux d’identification (par exemple, les numéros de sécurité sociale aux États-Unis), qui sont stockées dans Azure Cosmos DB. Always Encrypted permet aux clients de chiffrer des données sensibles dans des applications clientes sans jamais révéler les clés de chiffrement à la base de données.

Always Encrypted apporte des fonctionnalités de chiffrement côté client à Azure Cosmos DB. Le chiffrement de vos données côté client peut être requis dans les scénarios suivants :

  • Protection des données sensibles ayant des caractéristiques de confidentialité spécifiques : Always Encrypted permet aux clients de chiffrer des données sensibles dans leurs applications et de ne jamais révéler les données de texte brut ou les clés de chiffrement au service Azure Cosmos DB.
  • Implémentation du contrôle d’accès par propriété : Étant donné que le chiffrement est contrôlé avec les clés que vous possédez et gérez à partir d’Azure Key Vault, vous pouvez appliquer des stratégies d’accès pour contrôler les propriétés sensibles auxquelles chaque client a accès.

Concepts

Always Encrypted pour Azure Cosmos DB introduit de nouveaux concepts impliqués dans la configuration du chiffrement côté client.

Clés de chiffrement

Clés de chiffrement des données

Lorsque vous utilisez Always Encrypted, les données sont chiffrées à l’aide de clés de chiffrement de données (DEK) qui doivent être créées au préalable. Ces chiffrements sont stockés dans le service Azure Cosmos DB et sont définis au niveau de la base de données, de sorte qu’un DEK peut être partagé entre plusieurs conteneurs. La création des DEK est effectuée côté client à l’aide du SDK Azure Cosmos DB.

Vous pouvez :

  • Créez un DEK par propriété à chiffrer, ou
  • Utilisez le même DEK pour chiffrer plusieurs propriétés.

Clés gérées par le client

Avant que les DEK soient stockés dans Azure Cosmos DB, elles sont encapsulées par une clé gérée par le client (CMK). En contrôlant l’encapsulation et le désencapsulage des DEK, les CMK contrôlent efficacement l’accès aux données chiffrées à l’aide de leur chiffrement correspondant. Le stockage des clés CMK est conçu comme extensible, avec une implémentation par défaut attend que les clés soient stockées dans Azure Key Vault.

Clés de chiffrement

Stratégie de chiffrement

À l’instar d’une stratégie d’indexation, une stratégie de chiffrement est une spécification au niveau du conteneur qui décrit la façon dont les propriétés JSON doivent être chiffrées. Cette stratégie doit être fournie lors de la création du conteneur et elle est immuable. Dans la version actuelle, vous ne pouvez pas mettre à jour la stratégie de chiffrement.

Pour chaque propriété que vous souhaitez chiffrer, la stratégie de chiffrement définit :

  • Le chemin d’accès de la propriété sous la forme de /property. Seuls les chemins d’accès de niveau supérieur sont actuellement pris en charge. Les chemins d’accès imbriqués tels que /path/to/property ne sont pas pris en charge.
  • ID de la DEK à utiliser lors du chiffrement et du déchiffrement de la propriété.
  • Un type de chiffrement. Il peut être aléatoire ou déterministe.
  • L’algorithme de chiffrement à utiliser lors du chiffrement de la propriété. L’algorithme spécifié peut remplacer l’algorithme défini lors de la création de la clé s’ils sont compatibles.

Chiffrement aléatoire ou déterministe

Le service Azure Cosmos DB ne voit jamais le texte brut des propriétés chiffrées avec Always Encrypted. Toutefois, il prend toujours en charge certaines fonctionnalités d’interrogation sur les données chiffrées, en fonction du type de chiffrement utilisé pour une propriété. Always Encrypted prend en charge les deux types de chiffrement suivants :

  • Chiffrement déterministe : génère toujours la même valeur chiffrée pour une valeur de texte brut et une configuration de chiffrement données. L’utilisation du chiffrement déterministe permet aux requêtes d’appliquer des filtres d’égalité sur les propriétés chiffrées. Toutefois, elle peut permettre aux attaquants de deviner des informations sur les valeurs chiffrées en examinant les séquences dans la propriété chiffrée. C’est particulièrement vrai si l’ensemble de valeurs chiffrées possibles est restreint, par exemple Vrai/Faux ou Région Nord/Sud/Est/Ouest.

  • Le chiffrement aléatoire : il utilise une méthode qui chiffre les données de manière moins prévisible. Le chiffrement aléatoire est plus sécurisé, mais il empêche de filtrer les requêtes sur les propriétés chiffrées.

Consultez Génération du vecteur d’initialisation (IV) pour en savoir plus sur le chiffrement déterministe et aléatoire dans Always Encrypted.

Configurer Azure Key Vault

La première étape pour commencer avec Always Encrypted consiste à créer vos CMK dans Azure Key Vault :

  1. Créez une nouvelle instance d’Azure Key Vault ou accédez à une instance existante.
  2. Créez une nouvelle clé dans la section Clés.
  3. Une fois la clé créée, accédez à sa version actuelle et copiez son identificateur de clé complet :
    https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. Si vous omettez la version de clé à la fin de l’identificateur de clé, la version la plus récente de la clé est utilisée.

Ensuite, vous devez configurer la manière dont le SDK Azure Cosmos DB accédera à votre instance Azure Key Vault. Cette authentification est effectuée via une identité Microsoft Entra. Il est très probable que vous utilisiez l’identité d’une application Microsoft Entra ou une identité managée en tant que proxy entre votre code client et votre instance Azure Key Vault, même si n’importe quel type d’identité peut être utilisé. Procédez comme suit pour utiliser votre identité Microsoft Entra comme proxy :

  1. Depuis votre instance Azure Key Vault, accédez à la section Stratégies d’accès et ajoutez une nouvelle stratégie :

    1. Dans Autorisations de clé, sélectionnez Obtenir, Répertorier, Désencapsuler la clé, Encapsuler la clé, Vérifier et Signer.
    2. Dans Sélectionner un principal, recherchez votre identité Microsoft Entra.

Protéger votre CMK de la suppression accidentelle

Pour vous assurer que vous ne perdez pas l’accès à vos données chiffrées après la suppression accidentelle de vos CMK, il est recommandé de définir deux propriétés sur votre instance Azure Key Vault : la suppression réversible et la protection de purge.

Si vous créez une instance Azure Key Vault, activez ces propriétés lors de la création :

Capture d’écran des propriétés de suppression réversible et de protection contre le vidage pour une nouvelle instance Azure Key Vault.

Si vous utilisez une instance Azure Key Vault existante, vous pouvez vérifier que ces propriétés sont activées en examinant la section Propriétés dans le Portail Azure. Si une de ces propriétés n’est pas activée, consultez les sections intitulées « Activation de la suppression réversible » et « Activation de la protection de purge » dans l’un des articles suivants :

Initialiser le SDK

Notes

Always Encrypted pour Azure Cosmos DB est actuellement pris en charge :

Pour pouvoir utiliser la fonctionnalité Always Encrypted, une instance de KeyResolver doit être attachée à votre instance de Kit de développement logiciel (SDK) Azure Cosmos DB. Cette classe définie dans l’espace de noms Azure.Security.KeyVault.Keys.Cryptography est utilisée pour interagir avec le magasin de clés hébergeant vos clés CMK.

Les extraits de code suivants utilisent la classe DefaultAzureCredential pour récupérer l’identité Microsoft Entra à utiliser lorsque vous accédez à votre instance Azure Key Vault. Vous trouverez des exemples de création de différents types de classes TokenCredentialici.

Notes

Vous aurez besoin du Package Azure.Identity supplémentaire pour accéder aux classesTokenCredential.

var tokenCredential = new DefaultAzureCredential();
var keyResolver = new KeyResolver(tokenCredential);
var client = new CosmosClient("<connection-string>")
    .WithEncryption(keyResolver, KeyEncryptionKeyResolverName.AzureKeyVault);

Créer une clé de chiffrement des données

Pour que les données puissent être chiffrées dans un conteneur, une clé de chiffrement de données doit être créée dans la base de données parente.

La création d’une clé de chiffrement de données s’effectue en appelant la méthode CreateClientEncryptionKeyAsync et en passant :

  • Un identificateur de chaîne qui identifie de façon unique la clé dans la base de données.
  • L’algorithme de chiffrement destiné à être utilisé avec la clé. Un seul algorithme est actuellement pris en charge.
  • L’identificateur de clé de la CMK stockée dans Azure Key Vault. Ce paramètre est passé dans un objet EncryptionKeyWrapMetadata générique où :
    • type définit le type de programme de résolution de clé (par exemple, Azure Key Vault).
    • name peut être n’importe quel nom convivial de votre choix.
    • value doit être l’identificateur de clé.

    Important

    Une fois la clé créée, accédez à sa version actuelle et copiez son identificateur de clé complète : https://<my-key-vault>.vault.azure.net/keys/<key>/<version>. Si vous omettez la version de clé à la fin de l’identificateur de clé, la version la plus récente de la clé est utilisée.

    • algorithm définit l’algorithme à utiliser pour encapsuler la clé de chiffrement principale avec la clé gérée par le client.
var database = client.GetDatabase("my-database");
await database.CreateClientEncryptionKeyAsync(
    "my-key",
    DataEncryptionAlgorithm.AeadAes256CbcHmacSha256,
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

Créer un conteneur avec une stratégie de chiffrement

Spécifiez la stratégie de chiffrement au niveau du conteneur lors de la création du conteneur.

var path1 = new ClientEncryptionIncludedPath
{
    Path = "/property1",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Deterministic.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
var path2 = new ClientEncryptionIncludedPath
{
    Path = "/property2",
    ClientEncryptionKeyId = "my-key",
    EncryptionType = EncryptionType.Randomized.ToString(),
    EncryptionAlgorithm = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
};
await database.DefineContainer("my-container", "/partition-key")
    .WithClientEncryptionPolicy()
    .WithIncludedPath(path1)
    .WithIncludedPath(path2)
    .Attach()
    .CreateAsync();

Lire et écrire des données chiffrées

Mode de chiffrement des données

Chaque fois qu’un document est écrit dans Azure Cosmos DB, le SDK recherche la stratégie de chiffrement pour déterminer quelles propriétés doivent être chiffrées et comment. Le résultat du chiffrement est une chaîne de base 64.

Chiffrement de types complexes :

  • Lorsque la propriété à chiffrer est un tableau JSON, chaque entrée du tableau est chiffrée.

  • Lorsque la propriété à chiffrer est un objet JSON, seules les valeurs feuille de l’objet sont chiffrées. Les noms de sous-propriétés intermédiaires restent sous forme de texte brut.

Lire les éléments chiffrés

Aucune action explicite n’est requise pour déchiffrer les propriétés chiffrées lors de l’émission de lectures de points (extraction d’un seul élément par son ID et sa clé de partition), des requêtes ou de la lecture du flux de modification. La raison est la suivante :

  • Le SDK recherche la stratégie de chiffrement pour déterminer les propriétés qui doivent être déchiffrées.
  • Le résultat du chiffrement incorpore le type JSON d’origine de la valeur.

Notez que la résolution des propriétés chiffrées et leur déchiffrement ultérieur sont basés uniquement sur les résultats retournés par vos requêtes. Par exemple, si la propriété property1 est chiffrée mais est projetée dans property2 (SELECT property1 AS property2 FROM c), elle n’est pas identifiée comme une propriété chiffrée lorsqu’elle est reçue par le SDK.

Filtrer les requêtes sur les propriétés chiffrées

Lors de l’écriture de requêtes qui filtrent sur des propriétés chiffrées, une méthode spécifique doit être utilisée pour passer la valeur du paramètre de requête. Cette méthode prend les arguments suivants :

  • Nom du paramètre de requête.
  • Valeur à utiliser dans la requête.
  • Chemin d’accès de la propriété chiffrée (telle que définie dans la stratégie de chiffrement).

Important

Les propriétés chiffrées peuvent uniquement être utilisées dans les filtres d’égalité (WHERE c.property = @Value). Toute autre utilisation renverra des résultats imprévisibles et incorrects. Cette contrainte sera mieux appliquée dans les prochaines versions du SDK.

var queryDefinition = container.CreateQueryDefinition(
    "SELECT * FROM c where c.property1 = @Property1");
await queryDefinition.AddParameterAsync(
    "@Property1",
    1234,
    "/property1");

Lecture de documents lorsque seul un sous-ensemble de propriétés peut être déchiffré

Dans les situations où le client n’a pas accès à toutes les CMK utilisées pour chiffrer les propriétés, seul un sous-ensemble de propriétés peut être déchiffré lorsque les données sont lues. Par exemple, si property1 a été chiffré avec key1 et property2 avec key2, une application cliente qui a uniquement accès à key1 peut toujours lire les données, mais pas property2. Dans ce cas, vous devez lire vos données par le biais de requêtes SQL et projeter les propriétés que le client ne peut pas déchiffrer : SELECT c.property1, c.property3 FROM c.

Rotation de clés gérées par le client

Vous souhaiterez peut-être « faire pivoter » votre CMK (autrement dit, utiliser une nouvelle CMK au lieu de l’actuelle) si vous soupçonnez que la CMK actuelle a été compromise. Faire pivoter régulièrement les CMK est également une pratique de sécurité courante. Pour effectuer cette rotation, il vous suffit de fournir l’identificateur de clé de la nouvelle CMK qui doit être utilisée pour encapsuler une DEK spécifique. Notez que cette opération n’affecte pas le chiffrement de vos données, mais la protection de la DEK. L’accès à la CMK précédente ne doit pas être révoqué tant que la rotation n’est pas terminée.

await database.RewrapClientEncryptionKeyAsync(
    "my-key",
    new EncryptionKeyWrapMetadata(
        KeyEncryptionKeyResolverName.AzureKeyVault,
        "akvKey",
        "https://<my-key-vault>.vault.azure.net/keys/<new-key>/<version>",
        EncryptionAlgorithm.RsaOaep.ToString()));

Rotation de clé de chiffrement

L’exécution d’une rotation de clé de chiffrement de données n’est pas proposée en tant que fonctionnalité clé en main. Cela est dû au fait que la mise à jour d’un clé de chiffrement nécessite une analyse de tous les conteneurs dans lesquels cette clé est utilisée et un nouveau chiffrement de toutes les propriétés chiffrées avec cette clé. Cette opération ne peut se produire que côté client, car le service Azure Cosmos DB ne stocke pas plus qu’il ne consulte la valeur de texte brut de la clé de chiffrement.

Dans la pratique, une rotation de clé de chiffrement peut être effectuée en opérant une migration de données à partir des conteneurs concernés vers de nouveaux. Les nouveaux conteneurs peuvent être créés exactement de la même façon que ceux d’origine. Pour vous aider à opérer une telle migration de données, vous pouvez trouver un outil de migration autonome sur GitHub.

Ajout de propriétés chiffrées

L’ajout de propriétés chiffrées à une stratégie de chiffrement existante n’est pas pris en charge pour les raisons déjà exposées dans la section ci-dessus. Cette opération nécessite une analyse complète du conteneur pour s’assurer que toutes les instances des propriétés sont correctement chiffrées. Elle ne peut se produire que côté client. Tout comme une rotation de clé de chiffrement, l’ajout de propriétés chiffrées supplémentaires peut être effectué en opérant une migration de données vers un nouveau conteneur avec une stratégie de chiffrement appropriée.

Si vous disposez d’une certaine flexibilité quant à la façon dont de nouvelles propriétés chiffrées peuvent être ajoutées du point de vue du schéma, vous pouvez également tirer parti de la nature insensible au schéma d’Azure Cosmos DB. Si vous utilisez une propriété définie dans votre stratégie de chiffrement comme un « jeu de propriétés », vous pouvez ajouter d’autres propriétés en dessous sans contrainte. Par exemple, imaginons que property1 est défini dans votre stratégie de chiffrement et que vous écrivez initialement property1.property2 dans vos documents. Si, à un stade ultérieur, vous devez ajouter property3 en tant que propriété chiffrée, vous pouvez commencer à écrire property1.property3 dans vos documents. La nouvelle propriété sera également chiffrée automatiquement. Cette approche ne nécessite pas de migration de données.

Étapes suivantes