0

Le chiffrement et SQL Server – Episode 1 : Transparent Data Encryption (TDE) vs Always Encrypted

twitterlinkedinmail

Le chiffrement sous SQL Server n’est pas nouveau et il existe sous plusieurs formes, selon les versions. Les deux principales implémentations sont TDE (Transparent Data Encryption, qui est un chiffrement “at rest”) et Always Encrypted (chiffrement par colonne).

La première implémentation du chiffrement est arrivé en 2008 est TDE. C’est une solution assez simple à mettre en oeuvre et qui a le mérite de proposer un élément de réponse aux considérations RGPD.

Always Encrypted est une solution plus complexe à déployer qui nécessitera une évaluation des données à risque, table par table, colonne par colonne. L’architecture applicative devra également être considérée.

SQL Server TDE – chiffrement des données “at rest” :

TDE est apparu avec SQL Server 2008 et uniquement en édition Enterprise, ce qui était un frein à son déploiement pour beaucoup d’entreprise. Depuis SQL Server 2019, cette fonctionnalité est disponible dès l’édition Standard. Dans Azure avec SQL Database, tous les niveaux de service propose le chiffrement TDE et il est même activé par défaut.

L’idée avec TDE est d’appliquer un chiffrement, base de données par base de données, sur les fichiers de données et de log transactionnel. Si un backup de la base est réalisé, celui-ci ne sera qu’une retranscription des fichiers de la base de données et donc sera également chiffré.

Le chiffrement est basé soit sur un certificat ou une paire de clés asymétriques généré par SQL Server, soit par le module EKM. Dans les deux cas, une attention très importante devra être apportée à la sécurisation des clés de chiffrements. En effet, imaginons la destruction du serveur SQL pour une raison quelconque. Si on veut restaurer une sauvegarde d’une base de données sur un autre serveur, il faudra posséder la clé de chiffrement et la déployer sur ce nouveau serveur. En l’absence de cette clé, l’utilisation du backup sera impossible.

 

Par ailleurs, dans le cas d’une configuration en mirroring ou en AlwaysOn, il faudra copier la clé de chiffrement sur tous les réplicas afin que SQL Server puisse manipuler les données chiffrées.

En conséquence, on comprend bien que TDE a pour objectif de protéger les donnée contre un vol des fichiers de SQL Server : .mdf, .ndf, .ldf et les backups de ces bases de données.

L’accès dans le moteur de SQL Server étant “transparent” comme son nom l’indique, si l’attaque se fait à travers l’applicatif ou le moteur de SQL Server (parce qu’un compte sur le serveur ou dans le réseau a des privilèges suffisants de connexion à la base), cela n’apportera pas de sécurité supplémentaire.

En contrepartie de cette fonctionnalité, SQL Server va consommer un peu plus de ressource CPU pour manipuler ces données. Si vous comptez déployer TDE sur un serveur qui connait déjà une forte charge CPU : attention, donc !

Avant SQL Server 2016, la compression des backups est également problématique. En effet, la compression apporte un caractère aléatoire aux données dans les pages et donc diminue les répétitions de valeurs qui permettent à la compression d’apporter du gain. Ainsi donc, la compression des backups n’apportera quasiment aucun gain d’espace disque tout en consommant des cycles de CPU. Pour peu que vous ayez pris l’habitude de sauvegarder votre backup à un endroit avec un espace assez limité, l’activation de TDE va saturer ce volume et faire échouer vos backups.

A partir de SQL Server 2016, si on ajoute l’option MAXTRANSFERSIZE = 65536 (ou supérieur) à la commande de backup, l’algorithme de backup et chiffrement sera différent, permettant de gagner de l’espace disque.

A partir de SQL Server 2019 CU5, il n’y a plus besoin d’ajouter le paramètre MAXTRANSFERSIZE, du moment qu’il y a l’option COMPRESS d’activé, cela mettra la valeur à 128K et permettra automatiquement de gagner l’espace lié à la compression.

 

L’activation de TDE est relativement souple : elle va se faire en fond de tâche avec une consommation modérée de ressources, surtout depuis SQL 2016 où ce travail est dévolu au processeur par un accélérateur dédié (Intel AES-NI). Mais si votre serveur est déjà assez chargé niveau CPU, peut-être que cela peut valoir le coup de créer une base de test avec une copie d’une table et lancez le TDE uniquement sur cette base pour en voir l’impact.

Enfin, pensez bien à sauvegarder votre certificat TDE ou votre clé asymétrique de déchiffrement et mettez la à un voir deux endroits sécurisés. Peut-être une clé USB dans une coffre-fort ? Un NAS avec une solution de chiffrement tierce ? Dans tous les cas, il faut bien comprendre que si vous perdez cette clé et que vous rencontrez un problème sur votre serveur chiffré par TDE , vos données sont en grave péril.

 

SQL Server Always Encrypted – le chiffrement de bout en bout, par colonne :

La solution Always Encrypted est plus récente que TDE et est arrivé avec SQL Server 2016. Il n’est pas nécessaire d’être en édition Enterprise : c’est accessible dès l’édition Standard.

Contrairement à TDE qui va chiffrer l’intégralité de la base de données, Always Encrypted est une option qui s’active colonne par colonne, table par table. Le chiffrement/déchiffrement n’est pas non plus “interne” au serveur SQL, mais géré par l’application. Le but est de proposer que l’administrateur de l’infrastructure (l’administrateur système ou de base de données) ne soit pas en mesure de voir ces données. Seul l’applicatif sera capable de déchiffrer les données.

En effet : la philosophie de cette technologie est vraiment dans son nom “Always Encrypted” : toujours chiffré.

 

 

Dans ce schéma, on voit TDE entre la base et le stockage & backup : cela ne veut pas dire qu’AlwaysOn nécessite TDE. Mais l’addition de ces deux technologies permet un chiffrement exhaustif.

On voit également que le chiffrement se fait entre la base de données et l’appli. Cela veut dire qu’il faut penser au driver SQL qui sera utilisé pour se connecter à la base. Si à sa sortie Always Encrypted exigeait un driver ADO .Net , on peut désormais avoir recours à plus d’options. On peut ainsi utiliser Always Encrypted avec des drivers pour :

  • .NET Core & .NET Framework
  • JDBC
  • ODBC
  • PHP

Les pages de documentations pour l’utilisation de ces drivers dans le cadre Always Encrypted est disponible à partir d’ici : https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/always-encrypted-client-development?view=sql-server-ver16

Always Encrypted va nécessiter la génération de deux type de clés : les Column Encryption Keys (qui vont servir à chiffrer les données des colonnes) et les Column Master Keys (qui protège les Column Encryption Keys). Comme avec TDE on peut utiliser le magasin de certificat de Windows, Azure Key Vault, ou bien un HSM pour les stocker. Cependant, le but est de sortir cette Column Master Key du serveur SQL pour bien séparer les rôles : SQL Server stock de la donnée chiffrée, et le driver compatible Always Encrypted se charge de chiffrer/déchiffrer les données.

Une Column Encryption Key peut chiffrer une ou plusieurs colonnes. Une base de données peut gérer plusieurs Column Encryptions Keys pour gérer des cas métiers avec différents profils d’utilisateurs par exemple. L’algorithme utilisé est un AES-256.

Il y aura donc deux tâches qui devront être considéré spécifiquement : le provisionnements des clés dans un key store approprié (avec le Magasin de Certificats Windows ou Azure Key Vault dans la plupart des cas), et la rotation des clés (parce qu’elles ont été compromises ou bien parce que le certificat est arrivé à expiration après une certaine date). On peut réaliser ces tâches avec SSMS ou en PowerShell.

La bonne pratique est de générer ces clés sur une autre machine, comme par exemple le serveur d’application qui a de toute façon vocation à les avoir pour chiffrer/déchiffrer les données.

SQL Server lui ne possédera que les méta-données de ces clés, qui lui serviront à identifier les colonnes comme recevant ce chiffrement.

Une fois les clés générées, on peut procéder au chiffrement des colonnes. Cependant, il y a un choix à faire : le chiffrement peut-être déterministe ou bien aléatoire.

Un chiffrement déterministe renvoie la même valeur chiffrée pour la même donnée en entrée. Cela peut permettre de deviner certaines informations, mais cela permet aussi de réaliser des opérations comme une recherche d’égalité ( “ma_colonne = ma valeur” et donc jointures), des agrégats et des indexations.

Un chiffrement aléatoire ne renvoie pas les mêmes valeurs pour des données identiques en entrées. C’est plus sécurisé mais toutes ces opérations deviennent impossibles.

Quand cette déclaration est faite dans le modèle de données, et pour peu que l’on est accès à la Column Master Key ainsi que bien sûr un accès à la base, on peut lire et écrire des données chiffrées. Il faut également spécifier dans la chaine de connexion qu’Always Encrypted est activé (en ADO. Net : Column Encryption Setting=enabled , en JDBC : encrypt=true …).

Il existe quelques limitations à l’usage d’Always Encrypted. On notera parmi celles-ci les suivantes :

  • Impossible d’utiliser des colonnes de type xml, timestamp, rowversion, image, ntext, text, sql_variant, hierarchyid, geography, geometry, alias et les user-defined types.
  • Les chaines de caractères doivent avoir un collation de type _BIN2 pour faire du déterministe.
  • Le Full Text est bien entendu impossible.
  • Pas de contrainte de valeur par défaut.
  • Pas de Change Data Capture.
  • Pas de Dynamic Data Masking.
  • La réplication logique est impossible (AlwaysOn est possible).
  • Les requêtes distribuées sont impossibles.
  • Les requêtes cross-databases en joignant sur les colonnes (même avec chiffrement déterministe) sont impossibles.

Plus d’information : https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/always-encrypted-database-engine?view=sql-server-ver16

 

TDE vs Always Encrypted – synthèse des différences :

On peut voir une approche complémentaire de ces deux solutions technologique. Une première phase étant TDE qui est une protection “basique”. Always Encrypted vient ajouter une vraie notion de chiffrement applicative mais qui va nécessiter un travail de réflexion sur les colonnes et les tables à chiffrer. Et sans parler du fait que, si il y a une interface utilisateur devant l’application, il faudrait également que ce flux soit chiffré avec SSL/TLS.

On peut cependant faire la synthèse suivante :

Always EncryptedTDE
VersionA partir de 2016 + Azure SQL DatabaseA partir de 2008 + Azure SQL Database
EditionStandardEnterprise avant 2019
Chiffrement des données “at rest”OuiOui
Chiffrement des données en utilisationOuiNon
Données visibles par le DBA ?NonOui
Données chiffrées parCôté client (driver de l’applicatif)SQL Server
Fonctionne niveau :ColonneBase de données
Impact applicatifOui (limitations sur colonne chiffrée)Non
Protège les clés de chiffrementOuiNon
Nécessite un driver adaptéOuiNon

 

Nous reviendrons prochainement sur la mise en oeuvre technique de TDE et d’Always Encrypted ! Et n’hésitez pas à poser vos questions dans les commentaires.

Continuez votre lecture sur le blog :

twitterlinkedinmail

Vincent Delabre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.