E2EE (End-To-End Encryption) for Delphi

· Components

From version 2026.1.0 E2EE (End-To-End Encryption) is supported (only for eSeGeCe All-Access subscribers).

End-to-End Encryption (E2EE) ensures that only the communicating peers can read the content of exchanged messages. Even the server that routes the messages cannot decrypt them. This article explains how E2EE works between two peers using public-key cryptography to securely exchange messages.

E2EE Explained

Core Principles of E2EE

In a two-peer E2EE system:


Key Material Overview

Each peer (for example, Alice and Bob) has:

Public and private keys are mathematically linked, but knowing the public key does not reveal the private key.


Step 1: Public Key Exchange

Before encrypted communication can occur, Alice and Bob must know each other's public keys.

Typical approaches:

This exchange does not compromise security, because public keys are not secret.


Step 2: Establishing a Shared Secret (ECDH)

To encrypt messages efficiently, Alice and Bob first derive a shared secret using Elliptic Curve Diffie–Hellman (ECDH).

How ECDH Works Conceptually

Because of the mathematical properties of elliptic curves, both computations produce the same secret value, even though neither side ever transmits that secret.

At no point is the shared secret sent over the network.


Step 3: Deriving a Symmetric Encryption Key

The raw ECDH shared secret is not used directly for encryption. Instead, it is processed through a Key Derivation Function (KDF), typically a cryptographic hash such as SHA-256.

Purpose of key derivation:


The result is a symmetric encryption key known only to Alice and Bob.


Step 4: Encrypting the Message

When Alice wants to send a message to Bob:

  1. Alice converts the message into bytes.
  2. Alice encrypts the message using a symmetric cipher (commonly AES-GCM) with:
    • The derived symmetric key
    • A random initialization vector (IV)
  3. Alice sends the encrypted message and IV to Bob via the server.

AES-GCM is commonly used because it provides:



Step 5: Decrypting the Message

When Bob receives the encrypted message:

  1. Bob independently derives the same symmetric key using ECDH and the same KDF.
  2. Bob decrypts the message using the symmetric key and IV.
  3. If authentication succeeds, Bob obtains the original plaintext.

If the message has been altered or the wrong key is used, decryption fails.


Role of the Server

In this architecture, the server:


The server cannot:


This is the defining property of End-to-End Encryption.


Summary

End-to-End Encryption between two peers works by combining:

  1. Public-key cryptography (for key agreement)
  2. Symmetric cryptography (for efficient message encryption)
  3. Key derivation functions (for security and correctness)

The result is a system where:


This model is the cryptographic backbone of modern secure messaging systems. 

E2EE Sample

// ... 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;