veilletech.fr
16 sept. Feed du jour
#05 SYMFONY Article

Symfony 8.2 gère vos clés de chiffrement

La vraie question du chiffrement applicatif n'est pas de chiffrer, c'est de retrouver.

Symfony 8.2, attendu fin novembre 2026, ajoute le composant KeyManagement : une interface unique devant AWS KMS, Azure Key Vault, Google Cloud KMS et HashiCorp Vault, avec des backends libsodium et OpenSSL pour le développement. Le mode enveloppe chiffre localement en AES-256-GCM avec une clé de données fournie par le KMS, ce qui lève la limite de taille du mode direct (4 Ko sur AWS KMS). Deux ponts Doctrine apportent le chiffrement de colonne et l'index aveugle qui la rend cherchable.

3 min de lectureavancévidéo 1:18
Partager
Sommaire6 sections
  1. Ce qui se passe
  2. Les paquets
  3. Deux modes, et pourquoi le second gagne
  4. Le vrai problème : retrouver une ligne chiffrée
  5. Le détail qui fait la différence à l'échelle
  6. À retenir

Ce qui se passe

Premier article de la série des nouveautés de Symfony 8.2, attendu fin novembre 2026 : le composant KeyManagement, contribué par Florent Morselli. Il met AWS KMS, Azure Key Vault, Google Cloud KMS et HashiCorp Vault derrière une seule API.

Le problème qu'il adresse est banal et mal outillé : chiffrer des colonnes contenant des données personnelles, des documents téléversés ou des jetons d'API, avec une clé maîtresse qui ne quitte jamais le fournisseur et dont chaque usage est audité. Jusqu'ici, chaque fournisseur imposait son SDK et son procédé.

Les paquets

Paquet Rôle
symfony/key-management interfaces, chiffrement par enveloppe, backends locaux libsodium et OpenSSL
symfony/aws-key-management pont AWS KMS
symfony/azure-keyvault-key-management pont Azure Key Vault
symfony/google-cloud-key-management pont Google Cloud KMS
symfony/hashicorp-vault-key-management pont HashiCorp Vault
symfony/doctrine-dbal-key-management type de colonne chiffré
symfony/doctrine-orm-key-management attribut d'index aveugle

Le composant est marqué expérimental : son API peut encore changer en version mineure.

Deux modes, et pourquoi le second gagne

Le mode direct envoie la donnée au KMS et récupère le chiffré. Simple, mais borné par la taille acceptée par le fournisseur — 4 Ko sur AWS KMS. Réservé aux petites valeurs, un jeton par exemple.

Le mode enveloppe demande au KMS une clé de données fraîche, chiffre la donnée localement en AES-256-GCM, puis range dans l'Envelope cette clé de données elle-même chiffrée par la clé maîtresse. La donnée ne sort jamais de l'application, sa taille est libre, et la même enveloppe se déchiffre à l'identique quel que soit le backend qui l'a produite — tant que la clé maîtresse reste joignable. Votre code ne manipule jamais que l'identifiant de cette clé : un alias, un ARN, une URL.

Côté configuration, on déclare un ou plusieurs clients par DSN sous la clé key_management, puis on injecte EnvelopeEncrypterInterface (ou EncrypterInterface / DecrypterInterface pour le mode direct), avec l'attribut #[Target] pour désigner un client autre que celui par défaut. Le composant ajoute quatre commandes console — dont deux qui lisent l'entrée standard et écrivent sur la sortie, donc chaînables pour réencapsuler une enveloppe sous une autre clé — et un panneau dans la barre de débogage en environnement dev.

Le vrai problème : retrouver une ligne chiffrée

Le chiffrement est randomisé : deux lignes portant la même valeur produisent deux chiffrés différents, et WHERE email = ? ne correspond donc jamais à rien.

C'est à quoi sert l'attribut #[BlindIndexed] du pont ORM. Une colonne d'index stocke un condensé à clé de la valeur, que l'ORM remplit automatiquement à chaque flush. La recherche porte sur cet index, pas sur le chiffré. L'index est un service, qui a besoin d'un client KMS et d'une clé encapsulée créée par key-management:generate-data-key.

Le pont DBAL fournit de son côté EncryptedType, qui décore n'importe quel type Doctrine existant. Le nom du type est le vôtre : on liste les noms dans un service EncryptedTypes — chacun associé au type Doctrine qu'il enveloppe et à la clé sous laquelle il chiffre — et on appelle son register() depuis le boot() du kernel, pour que les types existent avant la première requête.

Le détail qui fait la différence à l'échelle

L'option key_management.store range les clés de données dans une table. Chaque ligne chiffrée ne porte plus alors qu'une référence de 16 octets au lieu d'une clé encapsulée complète, et le KMS n'est appelé qu'une fois par clé de données, non par ligne.

C'est ce qui rend possible la commande key-management:rewrap-data-keys : changer de clé maîtresse, ou même de fournisseur, réencapsule les clés stockées sans lire ni réécrire une seule ligne chiffrée.

À retenir

Le composant ne prétend pas rendre le chiffrement transparent — il rend transparent le changement de fournisseur, et fournit la pièce manquante des implémentations maison : une colonne chiffrée qu'on peut encore interroger. Statut expérimental oblige, on l'essaie sur une colonne, pas sur toute la base.