[SQL Server] Sécurité : introduction à Always Encrypted

Ce billet traite d’une nouvelle fonctionnalité de sécurité qui apparaît à partir de SQL Server 2016 : Always Encrypted.

Always Encrypted : kesako ?

Présentation d’Always Encrypted

Always Encrypted est une nouvelle fonctionnalité de SQL Server 2016 qui permet d’encrypter les données, qu’elles soient en mouvement ou non. Elle a pour avantage de protéger – dans la mesure du possible – les données contre d’éventuelles malversations (vol de backups, DBA « corrompus », etc…).

Le schéma ci-dessous, tiré de la documentation officielle de Microsoft, résume bien le fonctionnement d’Always Encrypted :


En quelques mots, Always Encrypted permet de faire en sorte que les données en clair ne soient révélées que seulement au sein d’une application métier. Ce sont les pilotes ADO.NET qui effectuent le chiffrement au niveau applicatif.

Cette fonctionnalité est basée sur divers éléments-clés constituant son architecture :

  • Column Encryption Key (colonne clé de cryptage) – c’est la clé de cryptage qui protège les colonnes à crypter.
  • Column Master Key (colonne clé maîtresse) : clé de cryptage qui protège les clé(s) de chiffrement de la colonne. Il est nécessaire d’avoir au moins une clé maîtresse avant de chiffrer toutes les colonnes.
  • Column-level enryption (paramètre de chiffrement au niveau de la colonne) : une colonne doit être réglée sur encrypted avec une clé de cryptage spécifique de la colonne, l’algorithme, et le type de chiffrement à utiliser :
    • Déterministe – chiffre toujours au même ciphertext (autrement dit, du code-texte), et plus adapté pour certaines opérations (lookups , distinct , groupement,…) et peut être indexé .
    • Aléatoire : généralement plus sûr, mais ne peut pas être évalué ou utilisé dans toutes les opérations (lecture/écriture uniquement) et ne peut pas être indexé (attention aux performances). .
  • Connection string (chaîne de connexion) : paramètre qui permet d’indiquer à une application cliente que la colonne cible est cryptée.

Scénarii d’utilisation

Pour reprendre la présentation officielle de Microsoft, il existe 3 principaux scénarii d’utilisation d’Always Encryption qui mettent en exergue son utilité :

  1. Application et base de données dans un cloud.

Utile si l’on souhaite réduire la surface d’attaque en permettant aux données d’être toujours chiffrées au sein du cloud.

  1. Application en local, avec base de données dans un cloud.

Utile notamment si l’on souhaite que les administrateurs cloud n’aient pas accès aux données sensibles en clair, grâce au stockage des clés en local.

  1. Application et base de données en local.

Utile si l’on souhaite que tous les DBA (prestataires externes, par exemple) n’aient pas accès aux données en clair, ou soient dans l’incapacité de les décrypter, car clés stockées dans un magasin local sécurisé.

Utilisation classique avec SQL Server

Au niveau de SQL Server, la mise en place d’Always Encrypted est assez simple. Typiquement, il suffit de suivre la roadmap suivante :

  • Création de la Column Master Key.


Dès l’ouverture de la boîte de dialogue, spécifiez le nom de la clé maîtresse et sa source :


Il existe diverses sources de clés :

  • Windows Certificate Store – Current User : magasin de certificats Windows. Ici, l’utilisateur actuel est utilisé comme contexte.
  • Windows Certificate Store Local Machine: magasin de certificats Windows au sein de la machine locale.
  • Azure Key Vault : chambre forte Azure. Ici, la clé est stockée au sein d’Azure.

En cas d’utilisation d’un magasin de certificats Windows, il faut penser à générer un certificat auto-signé.


  • Création de la Column Encryption Key.


Après l’ouverture de la boîte de dialogue, le nom de la clé, ainsi que celle de la clé maîtresse préalablement définie doivent être spécifiés.


Après validation, nous pouvons apercevoir les clés créées, au sein de l’explorateur d’objets de SQL Server Management Studio (SSMS) :


  • Création de la table à chiffrer.
CREATE TABLE dbo.AE_MyTable
(
	ID INT IDENTITY(1,1) PRIMARY KEY,
	LastName NVARCHAR(50),
	FirstName NVARCHAR(50),
	Age INT ENCRYPTED WITH
(
	ENCRYPTION_TYPE = RANDOMIZED,
	ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
	COLUMN_ENCRYPTION_KEY = AE_MyTable_CEK
),
	Country NVARCHAR(50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(
	ENCRYPTION_TYPE = DETERMINISTIC,
	ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
	COLUMN_ENCRYPTION_KEY = AE_MyTable_CEK
) )
GO

Ci-dessus, on a choisi de chiffrer 2 colonnes de 2 manières différentes : aléatoire pour l’âge, déterministe pour le pays.

Notez qu’il est tout à fait possible d’implémenter les clés en T-SQL pur, comme suit :

CREATE COLUMN MASTER KEY AE_MyTable_CMK
WITH (
	KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
	KEY_PATH = 'LocalServer/Mac/F9942E28D909D12C842A3d8e0b562E598JD09843'
);
CREATE COLUMN ENCRYPTION KEY AE_MyTable_CEK WITH VALUES
(
	COLUMN_MASTER_KEY = AE_MyTable_CMK,
	ALGORITHM = 'RSA_OAEP',
	ENCRYPTED_VALUE = 0x0287…
);
GO
 Limitations

Always Encrypted possède quelques limitations :

  • Toute colonne chiffrée de façon déterministe doit avoir une collation BIN2.
  • Les colonnes d’identité (IDENTITY) ne sont pas supportées. Ni celles calculées.
  • Les indexes et les contraintes ne peuvent être utilisés que dans un contexte de cryptage déterministe.
  • Les clés étrangères doivent être également chiffrées si les colonnes qu’elles référencient le sont déjà.
  • En cas de jointure entre 2 colonnes, ces dernières doivent utiliser la même clé de chiffrement.
  • Les opérateurs ensemblistes comme =>, <=, LIKE,… ne sont pas supportés sur des colonnes encryptées.
  • L’utilisation d’opérateurs de comparaison d’équalité n’est possible que si les colonnes concernées sont chiffrées de manière déterministe. Idem concernant DISTINCT et GROUP BY.
  • Tous les types de données ne sont pas supportés : XML, IMAGE, NTEXT, TEXT, HIERARCHYID, SQL_VARIANT, GEOGRAPHY, GEOMETRY, ROWVERSION. Ainsi que les types définis par les utilisateurs (user-defined types).
  • Les versions inférieures à 4.6 du framework .NET ne sont pas supportées par les pilotes de chiffrement ADO.NET.
  • Les tables optimisées en mémoire (In-Memory OLTP) ne sont pas supportées.
  • La fonctionnalité Stretch Database n’est pas supportée.
  • La fonctionnalité Full-Text Search n’est pas supportée.
  • Les tables temporaires ne sont pas supportées.
  • Les triggers ne sont pas pleinement supportés.

D’autres limitations existent. Plus de détails ici : https://msdn.microsoft.com/en-us/library/mt163865.aspx.

Pour aller plus loin…

Vous pouvez garder un œil ici pour d’autres sujets sur la sécurité.

Vous pouvez également aller ici pour consulter l’excellent billet de Greg Larsen qui montre comment exploiter la sécurité d’Always Encrypted via une application .NET.


Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s