Handshake Protocol
On this page
Nalix implements a high-security, zero-trust handshake protocol based on X25519 (Curve25519) Elliptic Curve Diffie-Hellman (ECDH). This protocol ensures that every session is encrypted with a unique session key that is never transmitted over the wire.
Source Mapping
src/Nalix.Codec/ProtocolFrames/SessionInit.cssrc/Nalix.Codec/ProtocolFrames/SessionChallenge.cssrc/Nalix.Codec/ProtocolFrames/SessionProof.cssrc/Nalix.Codec/ProtocolFrames/SessionEstablished.cssrc/Nalix.Codec/ProtocolFrames/SessionTofu.cssrc/Nalix.Codec/Security/HandshakeX25519.cssrc/Nalix.Runtime/Handlers/HandshakeHandlers.cssrc/Nalix.SDK/Transport/Extensions/HandshakeExtensions.cs
Security Guarantees
- Mutual Agreement: Both client and server contribute to the final session key.
- Perfect Forward Secrecy (PFS): Ephemeral keys are used for every session.
- Identity Verification: Requires pinned server Ed25519 public keys in production to prevent Man-in-the-Middle (MitM) attacks (or explicit Trust-On-First-Use via
SessionTofuwhenTransportOptions.AllowTofu = truein development). - Adaptive Proof-of-Work: When enabled, the server may require clients to solve a PoW puzzle before the handshake proceeds, throttling automated connection floods. See Proof-of-Work.
- Transcript Integrity: All handshake messages are hashed into a transcript to prevent tampering or replay attacks.
The Handshake Workflow
The diagram below illustrates the communication between the Nalix SDK and the Nalix Server handlers.
sequenceDiagram
participant SDK as Client
participant Srv as Server
Note over SDK: Generate KeyPair & Nonce
SDK->>Srv: SessionInit<br/>[PublicKey, Nonce]
Note over Srv: Resolve Handlers<br/>Generate SrvKeyPair<br/>Compute MasterSecret
Srv->>SDK: SessionChallenge<br/>[PublicKey, Nonce, Proof]
Note over SDK: Verify Proof<br/>Compute Secrets<br/>Derive SessionKey
SDK->>Srv: SessionProof<br/>[Proof]
Note over Srv: Verify Proof<br/>Create Session<br/>Finalize Cipher
Srv->>SDK: SessionEstablished<br/>[Proof, SessionToken]
Note over SDK: Verify Proof<br/>Enable AEAD EncryptionProtocol Stages
1. SessionInit
The SDK initiates by sending its ephemeral public key and a cryptographically secure random nonce via a SessionInit frame. No sensitive data is sent here.
2. SessionChallenge
The server responds with its own ephemeral public key and a Proof via a SessionChallenge frame. The proof is a keyed digest computed over the handshake transcript using the derived master secret (via HandshakeX25519.ComputeServerProof), proving the server possesses the corresponding private key without revealing it.
3. SessionProof
The SDK validates the server’s proof. If valid, it computes its own ClientProof and sends it back via a SessionProof frame. This confirms to the server that the client has successfully derived the same shared secret.
4. SessionEstablished
Final confirmation. The server sends a SessionEstablished frame containing the SessionToken. The SDK uses that token for UDP datagram authentication, and the connection is now fully encrypted using the derived session key.
Implementation Details
- Encryption:
src/Nalix.Runtime/Handlers/HandshakeHandlers.csandsrc/Nalix.SDK/Transport/Extensions/HandshakeExtensions.csset the active cipher toCipherSuiteType.Chacha20Poly1305for the established session. - Resume Token:
SessionEstablishedreturns the currentSessionToken, which the SDK later stores inSessionState.SessionToken.