E2EE (chiffrement de bout en bout) pour Delphi

· Composants

Depuis la version 2026.1.0, E2EE (chiffrement de bout en bout) est pris en charge (uniquement pour les abonnés eSeGeCe All-Access).

Le chiffrement de bout en bout (E2EE) garantit que seuls les pairs en communication peuvent lire le contenu des messages échangés. Même le serveur qui route les messages ne peut pas les déchiffrer. Cet article explique comment E2EE fonctionne entre deux pairs en utilisant la cryptographie à clé publique pour échanger des messages en toute sécurité.

E2EE expliqué

Principes fondamentaux d'E2EE

Dans un système E2EE à deux pairs :


Aperçu du matériel cryptographique

Chaque pair (par exemple, Alice et Bob) possède :

Les clés publique et privée sont mathématiquement liées, mais connaître la clé publique ne révèle pas la clé privée.


Étape 1 : échange de clés publiques

Avant que la communication chiffrée puisse avoir lieu, Alice et Bob doivent connaître les clés publiques l'un de l'autre.

Approches typiques :

Cet échange ne compromet pas la sécurité, car les clés publiques ne sont pas secrètes.


Étape 2 : établissement d'un secret partagé (ECDH)

Pour chiffrer efficacement les messages, Alice et Bob dérivent d'abord un secret partagé via Elliptic Curve Diffie–Hellman (ECDH).

Comment ECDH fonctionne conceptuellement

Grâce aux propriétés mathématiques des courbes elliptiques, les deux calculs produisent la même valeur secrète, même si aucun des deux côtés ne transmet jamais ce secret.

À aucun moment le secret partagé n'est envoyé sur le réseau.


Étape 3 : dériver une clé de chiffrement symétrique

Le secret partagé ECDH brut n'est pas utilisé directement pour le chiffrement. Au lieu de cela, il est traité via une fonction de dérivation de clé (KDF), typiquement un hachage cryptographique comme SHA-256.

Objectif de la dérivation de clé :


Le résultat est une clé de chiffrement symétrique connue uniquement d'Alice et Bob.


Étape 4 : chiffrer le message

Quand Alice veut envoyer un message à Bob :

  1. Alice convertit le message en octets.
  2. Alice chiffre le message avec un chiffrement symétrique (couramment AES-GCM) avec :
    • La clé symétrique dérivée
    • Un vecteur d'initialisation (IV) aléatoire
  3. Alice envoie le message chiffré et l'IV à Bob via le serveur.

AES-GCM est couramment utilisé car il fournit :



Étape 5 : déchiffrer le message

Quand Bob reçoit le message chiffré :

  1. Bob dérive indépendamment la même clé symétrique via ECDH et la même KDF.
  2. Bob déchiffre le message avec la clé symétrique et l'IV.
  3. Si l'authentification réussit, Bob obtient le texte en clair original.

Si le message a été altéré ou si une mauvaise clé est utilisée, le déchiffrement échoue.


Rôle du serveur

Dans cette architecture, le serveur :


Le serveur ne peut pas :


C'est la propriété déterminante du chiffrement de bout en bout.


Résumé

Le chiffrement de bout en bout entre deux pairs fonctionne en combinant :

  1. La cryptographie à clé publique (pour l'accord de clés)
  2. La cryptographie symétrique (pour le chiffrement efficace des messages)
  3. Les fonctions de dérivation de clés (pour la sécurité et la correction)

Le résultat est un système où :


Ce modèle est l'épine dorsale cryptographique des systèmes de messagerie sécurisée modernes. 

Exemple E2EE

// ... Create the Server
WSServer := TsgcWebSocketHTTPServer.Create(nil);
WSServer.Port := 80;
WSPE2EE := TsgcWSPServer_E2EE.Create(nil);
WSPE2EE.Server := WSServer;
WSServer.Active := True;
// ... Create 2 clients
WSClient1 := TsgcWebSocketClient.Create(nil);
WSClient1.Host := '127.0.0.1';
WSClient1.Port := 80;
E2EE1 := TsgcWSPClient_E2EE.Create(nil);
E2EE1.Client := WSClient1;
E2EE1.E2EE_Otpions.UserId := 'client-1';
WSClient1.Active := True;
WSClient2 := TsgcWebSocketClient.Create(nil);
WSClient2.Host := '127.0.0.1';
WSClient2.Port := 80;
E2EE2 := TsgcWSPClient_E2EE.Create(nil);
E2EE2.OnE2EEMessageText := OnE2EEMessageTextEvent;
E2EE2.E2EE_Otpions.UserId := 'client-2';
E2EE2.Client := WSClient2;
WSClient2.Active := True;
// ... client-1 send a message to client-2
E2EE1.SendDirectMessage('client-2', 'Hello Client-2');
// ... read the message in the OnE2EEMessageText event
procedure OnE2EEMessageText(Sender: TObject; const aFrom, aText: string);
begin
  DoLog('#direct_message: ' + aText);
end;