Dalla versione 2026.1.0 E2EE (End-To-End Encryption) è supportato (solo per i sottoscrittori eSeGeCe All-Access).
L'End-to-End Encryption (E2EE) garantisce che solo i peer in comunicazione possano leggere il contenuto dei messaggi scambiati. Anche il server che instrada i messaggi non può decifrarli. Questo articolo spiega come funziona E2EE tra due peer usando la crittografia a chiave pubblica per scambiare messaggi in modo sicuro.
E2EE spiegato
Principi fondamentali di E2EE
In un sistema E2EE tra due peer:
- Ogni peer possiede una chiave privata che non lascia mai il suo dispositivo.
- Ogni peer pubblica una chiave pubblica che gli altri possono vedere.
- I messaggi vengono cifrati sul dispositivo del mittente e decifrati solo sul dispositivo del destinatario.
- Il server agisce solo come relay di messaggi, non come parte fidata.
Panoramica del materiale crittografico
Ogni peer (ad esempio Alice e Bob) ha:
- Chiave privata
Un valore segreto memorizzato localmente. Non deve mai essere condiviso. - Chiave pubblica
Un valore derivato dalla chiave privata. Può essere condiviso liberamente.
Le chiavi pubblica e privata sono matematicamente collegate, ma conoscere la chiave pubblica non rivela la chiave privata.
Passo 1: scambio delle chiavi pubbliche
Prima che possa avvenire una comunicazione cifrata, Alice e Bob devono conoscere le rispettive chiavi pubbliche.
Approcci tipici:
- Il server memorizza le chiavi pubbliche e le consegna su richiesta.
- Le chiavi pubbliche vengono scambiate al momento della creazione dell'account o al primo contatto.
Questo scambio non compromette la sicurezza, perché le chiavi pubbliche non sono segrete.
Passo 2: stabilire un segreto condiviso (ECDH)
Per cifrare i messaggi in modo efficiente, Alice e Bob derivano prima un segreto condiviso usando Elliptic Curve Diffie-Hellman (ECDH).
Come funziona ECDH a livello concettuale- Alice calcola un segreto condiviso usando:
- La sua chiave privata
- La chiave pubblica di Bob
- Bob calcola un segreto condiviso usando:
- La sua chiave privata
- La chiave pubblica di Alice
Grazie alle proprietà matematiche delle curve ellittiche, entrambi i calcoli producono lo stesso valore segreto, anche se nessuno dei due lati trasmette mai quel segreto.
In nessun momento il segreto condiviso viene inviato sulla rete.
Passo 3: derivare una chiave di cifratura simmetrica
Il segreto condiviso ECDH grezzo non viene usato direttamente per la cifratura. Viene invece elaborato attraverso una Key Derivation Function (KDF), tipicamente un hash crittografico come SHA-256.
Scopo della derivazione di chiave:
- Produrre una chiave della lunghezza corretta (ad esempio 32 byte per AES-256)
- Rimuovere bias strutturali dall'output ECDH grezzo
- Migliorare la robustezza crittografica
Il risultato è una chiave di cifratura simmetrica nota solo ad Alice e Bob.
Passo 4: cifratura del messaggio
Quando Alice vuole inviare un messaggio a Bob:
- Alice converte il messaggio in byte.
- Alice cifra il messaggio usando un cifrario simmetrico (comunemente AES-GCM) con:
- La chiave simmetrica derivata
- Un vettore di inizializzazione (IV) casuale
- Alice invia a Bob il messaggio cifrato e l'IV tramite il server.
AES-GCM è comunemente usato perché fornisce:
- Riservatezza (cifratura)
- Integrità (rilevamento di manomissioni)
- Autenticazione (rileva messaggi falsificati)
Passo 5: decifratura del messaggio
Quando Bob riceve il messaggio cifrato:
- Bob deriva indipendentemente la stessa chiave simmetrica usando ECDH e la stessa KDF.
- Bob decifra il messaggio usando la chiave simmetrica e l'IV.
- Se l'autenticazione ha successo, Bob ottiene il testo in chiaro originale.
Se il messaggio è stato alterato o se viene usata la chiave sbagliata, la decifratura fallisce.
Ruolo del server
In questa architettura, il server:
- Consegna le chiavi pubbliche
- Instrada i messaggi cifrati
- Gestisce la presenza utente o i metadati
Il server non può:
- Derivare segreti condivisi
- Decifrare i messaggi
- Falsificare messaggi cifrati validi
Questa è la proprietà che definisce l'End-to-End Encryption.
Riepilogo
L'End-to-End Encryption tra due peer funziona combinando:
- Crittografia a chiave pubblica (per l'accordo di chiave)
- Crittografia simmetrica (per cifrare i messaggi in modo efficiente)
- Funzioni di derivazione di chiave (per sicurezza e correttezza)
Il risultato è un sistema in cui:
- Solo i peer possono leggere i messaggi
- Il server è ridotto a un ruolo di trasporto
- La privacy è preservata per design, non per policy
Questo modello è la spina dorsale crittografica dei moderni sistemi di messaggistica sicura.
Esempio 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;
