SQL Server 2016 Always Encrypted : facile à mettre en œuvre, difficile à casser

Publié: 2022-03-11

Les données sont un actif clé de toute entreprise, en particulier les données transactionnelles qui contiennent des secrets commerciaux tels que les dossiers financiers ou de santé. Les données sont plus vulnérables lorsqu'elles transitent entre le serveur qui les stocke et le client qui les demande.

L'approche standard pour assurer la sécurité consiste à chiffrer les données sur le serveur et à utiliser le protocole HTTPS compatible SSL pour sécuriser les données en cours de transport. Cependant, que se passerait-il si nous pouvions encore augmenter le niveau de sécurité, en utilisant HTTPS et en envoyant des données dans un format crypté sur la ligne de communication, uniquement pour décrypter les données sur les clients qui ont des certificats valides ? Cette approche rendrait une attaque traditionnelle de l'homme du milieu (MITM) beaucoup plus difficile.

Image de couverture du chiffrement SQL Server

La solution de Microsoft à ce problème est Always Encrypted, un moyen d'envoyer des données chiffrées sur le pipeline et de les déchiffrer uniquement par les utilisateurs ayant accès à des certificats valides. Ainsi, même si l'attaquant obtient les données, sans un certificat approprié stocké sur la machine cliente, les données seraient inutiles.

Cet article décrit comment configurer et utiliser Always Encrypted, et il est recommandé de le lire à toute personne qui envoie des données importantes sur les lignes de communication publiques, même si elles sont sécurisées avec SSL.

Le concept derrière Always Encrypted

Always Encrypted est une technologie de chiffrement côté client que Microsoft a introduite avec SQL Server 2016. Always Encrypted conserve les données automatiquement chiffrées, non seulement lorsqu'elles sont écrites, mais également lorsqu'elles sont lues par une application approuvée. Contrairement à Transparent Data Encryption, qui chiffre les données et les fichiers journaux sur le disque en temps réel, mais permet aux données d'être lues par toute application qui interroge les données, Always Encrypted nécessite que votre application cliente utilise un pilote compatible Always Encrypted pour communiquer avec le base de données. En utilisant ce pilote, l'application transfère en toute sécurité les données chiffrées vers la base de données qui ne peuvent ensuite être déchiffrées ultérieurement que par une application ayant accès à la clé de chiffrement. Toute autre application interrogeant les données peut également récupérer les valeurs chiffrées, mais cette application ne peut pas utiliser les données sans la clé de chiffrement, rendant ainsi les données inutiles. En raison de cette architecture de chiffrement, l'instance SQL Server ne voit jamais la version non chiffrée des données.

À l'heure actuelle, les seuls pilotes compatibles avec Always Encrypted sont le fournisseur de données .NET Framework pour SQL Server, qui nécessite l'installation de .NET Framework version 4.6 sur l'ordinateur client, et le pilote JDBC 6.0. Cela changera probablement avec le temps, mais ce sont les exigences officielles de Always Encrypted en avril 2017.

Mais pourquoi avons-nous besoin de cette technologie ? Il y a quelques bonnes raisons pour lesquelles Always Encrypted devrait être utilisé :

  • Sécurité — Les données devaient toujours être sécurisées. Maintenant que SSL est compromis, Always Encrypted comble le vide avec une autre couche de protection du pipeline de transport.
  • Support réglementaire - Les données doivent être cryptées et protégées des regards indiscrets des DBA par de plus en plus de réglementations sectorielles, principalement dans les secteurs de la finance et des télécommunications. Ceci est décrit dans la norme PII ("Personally Identifiable Information") qui stipule que des éléments tels que les numéros de carte de crédit, les numéros de sécurité sociale, les noms et les adresses doivent être protégés, sinon le propriétaire des données peut être sévèrement pénalisé.

Comment utiliser Always Encrypted

L'utilisation d'Always Encrypted nécessite une petite quantité de préparation au sein du serveur de base de données stockant les tables chiffrées. La préparation est un processus en deux étapes :

  • Créer la définition de clé principale de colonne
  • Créer la clé de chiffrement de colonne

Clé principale de colonne

Qu'est-ce qu'une clé principale de colonne ?

Clé principale de colonne dans SQL Server 2016

La clé principale de colonne est un certificat stocké dans un magasin de certificats Windows (qui est utilisé dans la démo comme option de stockage de certificats), un module de sécurité matériel tiers (un nom générique pour les solutions tierces d'installation, de gestion et d'utilisation certificates ) ou Azure Key Vault (la solution basée sur le cloud de Microsoft pour la gestion des certificats).

L'application qui chiffre les données utilise la clé principale de colonne pour protéger diverses clés de chiffrement de colonne qui gèrent le chiffrement des données dans les colonnes d'une table de base de données. L'utilisation de magasins de certificats de SQL Server, parfois appelés Enterprise Key Manager , nécessite l'utilisation de SQL Server Enterprise Edition.

Dans cet article, nous décrivons l'utilisation d'un certificat auto-signé que vous stockez dans le Microsoft Certificate Store du système d'exploitation Windows. Bien que cette approche ne soit pas la configuration optimale, elle démontre le concept de Always Encrypted, mais il faut également préciser que cette approche n'est pas acceptable pour les environnements de production , où la gestion des certificats doit être effectuée avec des comptes d'utilisateurs séparés et sécurisés et, de préférence , sur des serveurs distincts.

Vous pouvez créer une définition de clé principale de colonne à l'aide de l'interface graphique dans SQL Server Management Studio (SSMS) ou à l'aide de T-SQL. Dans SSMS, connectez-vous à l'instance de base de données SQL Server 2016 dans laquelle vous souhaitez utiliser Always Encrypted pour protéger une table de base de données.

Création et utilisation de clés principales de colonne

Dans l'Explorateur d'objets, accédez d'abord à la base de données, puis à Sécurité, puis développez le dossier Clés toujours chiffrées pour afficher ses deux sous-dossiers, comme illustré dans les figures suivantes :

Créez une clé dans SSMS.

Créez une clé dans SSMS.

Ouvrez une nouvelle boîte de dialogue Clé principale de colonne.

Ouvrir une nouvelle boîte de dialogue Clé principale de colonne

Vérifiez l'existence de la clé dans le magasin de certificats Windows.

Vérifiez l'existence de la clé dans le magasin de certificats Windows

Pour créer la clé principale de colonne, cliquez avec le bouton droit sur le dossier Column Master Keys et sélectionnez New Column Master Key . Dans la boîte de dialogue New Column Master Key , tapez un nom pour la clé principale de colonne, spécifiez si vous souhaitez stocker la clé dans le magasin de certificats de l'utilisateur actuel ou de l'ordinateur local ou dans Azure Key Vault, puis sélectionnez un certificat dans la liste. S'il n'y a pas de certificats, ou si vous souhaitez utiliser un nouveau certificat auto-signé, cliquez sur le bouton Generate Certificate , puis cliquez sur OK . Cette étape crée un certificat auto-signé et le charge dans le magasin de certificats du compte d'utilisateur actuel exécutant SSMS.

Remarque : vous devez effectuer ces étapes sur une machine approuvée, mais pas sur l'ordinateur hébergeant votre instance SQL Server. De cette façon, les données restent protégées dans SQL Server même si l'ordinateur hôte est compromis.

Ainsi, après avoir créé le certificat et l'avoir configuré comme clé principale de colonne, vous devez l'exporter et le distribuer à tous les ordinateurs hébergeant des clients nécessitant un accès aux données. Si une application cliente est basée sur le Web, vous devez charger le certificat sur le serveur Web. S'il s'agit d'une application installée sur les ordinateurs des utilisateurs, vous devez déployer le certificat sur l'ordinateur de chaque utilisateur individuellement.

Vous pouvez trouver des instructions applicables pour exporter et importer des certificats pour votre système d'exploitation aux URL suivantes :

  • Exportation de certificats
    • Windows 7 et Windows Server 2008 R2
    • Windows 8 et Windows Serveur 2012
    • Windows 8.1 et Windows Server 2012 R2
    • Windows 10 et Windows Serveur 2016
  • Importation de certificats
    • Windows 7 et Windows Server 2008 R2
    • Windows 8 et Windows Serveur 2012
    • Windows 8.1 et Windows Server 2012 R2
    • Windows 10 et Windows Serveur 2016

Lorsque vous importez des certificats dans le magasin de certificats sur des ordinateurs avec une application qui chiffre et déchiffre les données, vous devez importer les certificats dans le magasin de certificats de la machine ou dans le magasin de certificats du compte de domaine exécutant l'application.

Clé de chiffrement de colonne

Après avoir créé une clé principale de colonne, vous êtes prêt à créer des clés de chiffrement pour des colonnes spécifiques. Le pilote SQL Server 2016 ADO.NET utilise des clés de chiffrement de colonne pour chiffrer les données avant de les envoyer à SQL Server et pour déchiffrer les données après les avoir extraites de l'instance SQL Server 2016. Comme pour la clé principale de colonne, vous pouvez créer des clés de chiffrement de colonne à l'aide de T-SQL ou SSMS. Alors que les clés principales de colonne sont plus faciles à créer à l'aide de T-SQL, les clés de chiffrement de colonne sont plus faciles à créer à l'aide de SSMS.

Pour créer une clé de chiffrement de colonne, utilisez l' Object Explorer pour vous connecter à l'instance de base de données, accédez à la base de données, puis à Security et développez le dossier Always Encrypted Keys . Cliquez avec le bouton droit sur Column Encryption Keys , puis sélectionnez New Column Encryption Key . Dans la boîte de dialogue New Column Encryption Key , saisissez un nom pour la nouvelle clé de chiffrement, sélectionnez une Column Master Key Definition dans la liste déroulante, puis cliquez sur OK . Vous pouvez maintenant utiliser la clé de chiffrement de colonne dans la définition d'une nouvelle table.

Création de clé de chiffrement de colonne

Cryptage SQL : création de la clé de cryptage de colonne, image 1

Cryptage SQL : création de la clé de cryptage de colonne, image 2

Création d'une table avec des valeurs chiffrées

Après avoir créé la définition de clé principale de colonne et les clés de chiffrement de colonne, vous pouvez créer une table pour contenir les valeurs chiffrées.

Avant cela, vous devez décider du type de chiffrement à utiliser, des colonnes à chiffrer et si vous pouvez indexer ces colonnes. Avec la fonctionnalité Always Encrypted , vous définissez normalement les tailles de colonne et SQL Server ajuste la taille de stockage de la colonne en fonction des paramètres de chiffrement. Après avoir créé votre table, vous devrez peut-être modifier votre application pour exécuter des commandes sur cette table à l'aide de Always Encrypted .

Types de chiffrement SQL Server 2016

Avant de créer une table pour contenir des valeurs chiffrées, vous devez décider si chaque colonne doit être chiffrée ou non.

Tout d'abord, cette colonne sera-t-elle utilisée pour rechercher des valeurs ou simplement pour renvoyer ces valeurs ?

Si la colonne doit être utilisée pour des recherches, elle doit utiliser un type de chiffrement déterministe , qui autorise les opérations d'égalité. Cependant, la recherche de données chiffrées à l'aide de la fonction Toujours chiffré est limitée. SQL Server 2016 prend uniquement en charge les opérations d'égalité, qui incluent equal to , not equal to , les joins (qui utilisent l'égalité) et l'utilisation de la valeur dans la clause GROUP BY . Toute recherche utilisant LIKE n'est pas prise en charge. De plus, le tri des données chiffrées à l'aide de Always Encrypted doit être effectué au niveau de l'application, car SQL Server effectuera le tri en fonction de la valeur chiffrée plutôt que de la valeur déchiffrée.

Si la colonne n'est pas destinée à être utilisée pour localiser des enregistrements, elle doit utiliser le type de cryptage aléatoire. Ce type de chiffrement est plus sécurisé, mais il ne prend pas en charge les opérations de recherche, de jointure ou de regroupement.

Créer une table avec des colonnes chiffrées

Lors de la création de tables, vous utilisez la syntaxe normale CREATE TABLE avec quelques paramètres supplémentaires dans la définition de colonne. Trois paramètres sont utilisés dans la syntaxe ENCRYPTED WITH pour l'instruction CREATE TABLE .

Le premier d'entre eux est le paramètre ENCRYPTION_TYPE , qui accepte une valeur de RANDOMIZED ou DETERMINISTIC . Le second est le paramètre ALGORITHM , qui n'accepte qu'une valeur de RAEAD_AES_256_CBC_HMAC_SHA_256 . Le troisième paramètre est COLUMN_ENCRYPTION_KEY , qui est la clé de chiffrement que vous utilisez pour chiffrer la valeur.

 CREATE TABLE [dbo].[Customers] ( [CustomerId] [int] IDENTITY(1,1), [TaxId] [varchar](11) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = YOUR_COLUMN_ENCRYPTION_KEY) NOT NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [MiddleName] [nvarchar](50) NULL, [Address1] [nvarchar](50) NULL, [Address2] [nvarchar](50) NULL, [Address3] [nvarchar](50) NULL, [City] [nvarchar](50) NULL, [PostalCode] [nvarchar](10) NULL, [State] [char](2) NULL, [BirthDate] [date] ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = YOUR_COLUMN_ENCRYPTION_KEY) NOT NULL PRIMARY KEY CLUSTERED ([CustomerId] ASC) ON [PRIMARY] ); GO

Indexation avec Always Encrypted

Les colonnes contenant des données chiffrées peuvent être utilisées comme colonnes de clé dans les index, à condition que ces colonnes soient chiffrées à l'aide du type de chiffrement DETERMINISTIC . Les colonnes chiffrées à l'aide du type de chiffrement RANDOMIZED renvoient un message d'erreur lorsque vous essayez de créer un index sur ces colonnes. Les colonnes chiffrées à l'aide de l'un ou l'autre des types de chiffrement peuvent être utilisées comme colonnes INCLUDE dans des index non clusterisés.

Étant donné que les valeurs chiffrées peuvent être des index, aucune mesure de réglage des performances supplémentaire n'est requise pour les valeurs chiffrées avec Always Encrypted au-delà de l'indexation et du réglage que vous effectuez normalement. Une bande passante réseau supplémentaire et des E/S plus importantes sont les seuls effets secondaires résultant de l'augmentation de la taille des valeurs renvoyées.

Performances toujours cryptées

Les performances sont toujours un facteur clé, en particulier dans ce cas, lorsque nous ajoutons une surcharge de chiffrement au trafic habituel de la base de données. Le meilleur site pour tester les performances est SQL Performance, qui a testé l'exécution des requêtes et l'utilisation du disque dans différents scénarios :

Tests de résultats de performances SQL Server Always Encrypted.

Tests de résultats de performances SQL Server Always Encrypted, image 1

Tests de résultats de performances SQL Server Always Encrypted, image 2

Comme il y a du travail sur le processeur et le disque dur qui doit être effectué avec les processus de cryptage et de décryptage, il y a un impact évident sur la quantité d'espace de stockage utilisé et la durée des requêtes. Comme cela dépend de votre environnement (fonctionnalités du processeur, de la RAM et du disque), vous devez tester si cela posera un problème en production.

Remarque : Si vous souhaitez en savoir plus sur l'optimisation des performances de Microsoft SQL Server, veuillez consulter l'un de nos articles précédents, Comment régler Microsoft SQL Server pour les performances.

Modifications des applications

Que devez-vous faire pour implémenter correctement Always Encrypted dans le code hérité ?

L'un des avantages de la fonctionnalité Always Encrypted de SQL Server 2016 est que les applications utilisant déjà des procédures stockées, des ORM ou des commandes T-SQL paramétrées ne devraient nécessiter aucune modification de l'application pour utiliser Always Encrypted, à moins que des opérations sans égalité ne soient déjà utilisées. Les applications qui créent des instructions SQL en tant que SQL dynamique dans l'application et exécutent ces commandes directement sur la base de données doivent être modifiées pour utiliser le paramétrage de leurs requêtes, une meilleure pratique de sécurité recommandée pour toutes les applications, avant de pouvoir tirer parti de la fonctionnalité Always Encrypted.

Une autre modification requise pour que Always Encrypted fonctionne est l'ajout d'un attribut de chaîne de connexion à la chaîne de connexion de l'application se connectant à la base de données : Column Encryption Setting=enabled .

Avec ce paramètre ajouté à la chaîne de connexion, le pilote ADO.NET demande à SQL Server si la commande en cours d'exécution inclut des colonnes chiffrées et, le cas échéant, quelles colonnes sont chiffrées. Pour les applications à charge élevée, l'utilisation de ce paramètre peut ne pas être la meilleure pratique, en particulier si un grand pourcentage des commandes en cours d'exécution n'incluent pas de valeurs chiffrées.

Par conséquent, le .NET Framework fournit une nouvelle méthode sur l'objet SqlConnection appelée SqlCommandColumnEncryptionSetting , qui a trois valeurs possibles :

  • Disabled — Il n'y a pas de colonnes ou de paramètres Always Encrypted à utiliser pour les requêtes qui sont exécutées à l'aide de cet objet de connexion.
  • Enabled : des colonnes et/ou des paramètres Always Encrypted sont utilisés pour les requêtes exécutées à l'aide de cet objet de connexion.
  • ResultSet — Il n'y a pas de paramètres Always Encrypted. Cependant, l'exécution de requêtes à l'aide de cet objet de connexion renvoie des colonnes chiffrées à l'aide de Always Encrypted.

Remarque : Sachez que l'utilisation de cette méthode peut potentiellement nécessiter une quantité importante de modifications de votre code d'application. Une approche alternative consiste à refactoriser votre application pour utiliser différentes connexions.

Pour optimiser les performances de SQL Server, il est judicieux de demander uniquement les métadonnées relatives à Always Encrypted pour les requêtes qui utilisent Always Encrypted. Cela signifie que dans les applications pour lesquelles un grand pourcentage de requêtes utilisent Always Encrypted, la chaîne de connexion doit être activée et les requêtes spécifiques au sein de l'application doivent spécifier SqlCommandColumnEncryptionSetting comme Disabled . Pour les applications pour lesquelles la plupart des requêtes n'utilisent pas les valeurs Always Encrypted, la chaîne de connexion ne doit pas être activée et SqlCommandColumnEncryptionSetting doit être défini sur Enabled ou ResultSet selon les besoins pour les requêtes qui utilisent des colonnes Always Encrypted. Dans la plupart des cas, les applications peuvent simplement activer l'attribut de chaîne de connexion et les performances de l'application resteront inchangées lors de l'utilisation des données chiffrées.

Est-ce que Always Encrypted en vaut la chandelle ?

Réponse courte? Oui définitivement!

Non seulement cela aide à prévenir de nombreux problèmes de sécurité potentiels et fournit aux développeurs SQL des fonctionnalités de sécurité supplémentaires, mais cela rend également votre système plus conforme, ce qui est vital dans de nombreux secteurs, des télécommunications à la banque et à l'assurance. Il est également important de noter que compte tenu des prérequis techniques mentionnés dans l'article, Always Encrypted peut être implémenté avec des modifications d'application minimales sur les systèmes existants .

Bien que vous puissiez utiliser des solutions personnalisées pour obtenir le même effet, cette technologie est fournie avec la nouvelle version de SQL Server et peut être utilisée prête à l'emploi. Il est également important de noter, comme il s'agit d'une nouvelle technologie, qu'il existe encore des limites à son utilisation et qu'elle ajoute des exigences matérielles supplémentaires.

Cependant, à moins qu'ils ne soient un facteur décisif pour votre environnement et que vous disposiez d'une application distribuée en dehors de l'intranet de votre entreprise, il n'y a pratiquement aucune raison de ne pas utiliser Always Encrypted.