Sécurité

Chiffrement AES-256-GCM

Dans une architecture flat-file, les paramètres de configuration sensibles — notamment le mot de passe SMTP — sont stockés en clair dans un fichier JSON. Si ce fichier est lisible par un tiers (mauvaise configuration de permissions, backup exposé, accès FTP compromis), le mot de passe est directement compromis. QuietCMS résout ce problème en chiffrant ces valeurs avec AES-256-GCM avant de les écrire sur le disque.

Pourquoi AES-256-GCM

AES-256-GCM est un mode AEAD (Authenticated Encryption with Associated Data) : il garantit simultanément la confidentialité (le contenu est illisible sans la clé) et l'intégrité (toute modification du chiffré est détectable). Contrairement à AES-CBC qui ne produit qu'un chiffré, GCM génère également un tag d'authentification de 128 bits. Si le chiffré ou le tag a été altéré, le déchiffrement échoue explicitement — il n'y a pas de risque de déchiffrer silencieusement des données corrompues ou falsifiées.

Génération de la clé

À l'installation, une clé de 256 bits est générée via random_bytes(32) et stockée encodée en base64 dans config.php :

define('ENCRYPTION_KEY', base64_encode(random_bytes(32)));

Cette clé ne change jamais après l'installation. La sécurité du chiffrement repose entièrement sur la confidentialité de config.php, qui doit être placé hors de la racine web ou protégé par des permissions 600.

Implémentation PHP : chiffrement

La méthode Security::encrypt() suit ce protocole :

  1. Génération d'un IV (vecteur d'initialisation) de 96 bits (12 octets) aléatoire via random_bytes(12). Un IV unique par opération de chiffrement est impératif avec GCM.
  2. Chiffrement avec openssl_encrypt() en mode aes-256-gcm.
  3. Récupération du tag GCM via openssl_encrypt (paramètre $tag passé par référence).
  4. Concaténation IV + TAG + CHIFFRÉ et encodage en base64 pour un stockage sûr dans le JSON.
public static function encrypt(string $plaintext): string
{
    $key = base64_decode(ENCRYPTION_KEY);
    $iv  = random_bytes(12); // 96 bits pour GCM
    $tag = '';

    $ciphertext = openssl_encrypt(
        $plaintext,
        'aes-256-gcm',
        $key,
        OPENSSL_RAW_DATA,
        $iv,
        $tag,
        '',
        16 // tag length 128 bits
    );

    return base64_encode($iv . $tag . $ciphertext);
}

Déchiffrement et rétrocompatibilité

Au déchiffrement, la méthode extrait les 12 premiers octets (IV), les 16 suivants (TAG) et le reste (CHIFFRÉ), puis appelle openssl_decrypt(). Si le déchiffrement échoue — ce qui arriverait pour une valeur en clair stockée avant la mise en place du chiffrement — la méthode retourne la valeur brute. Ce mécanisme de fallback assure la rétrocompatibilité lors des migrations.

Portée du chiffrement

Seul le mot de passe SMTP est chiffré dans settings.json. Il est déchiffré en mémoire uniquement au moment de l'envoi d'un e-mail, puis immédiatement abandonné. Les autres paramètres (titre du site, thème actif…) restent en clair car ils ne présentent pas de risque de confidentialité.

Ce périmètre délibérément limité évite une complexité inutile : chiffrer des données non sensibles n'apporte aucun bénéfice de sécurité mais augmente la surface de code à maintenir et les risques de perte de données en cas de rotation de clé mal gérée.

Articles similaires