We covered Diffie-Hellman conceptually earlier in the book. Now letâs see exactly how it works inside a TLS 1.2 handshake with ECDHE.
Before we look at the diagram, thereâs an important point that trips people up. The server has two separate key pairs that serve completely different purposes:
The long-term key pair (from the certificate). This key pair lives on the server for months or years. The private key is used only for signing. It proves the serverâs identity. It is never used for encryption or key exchange.
The ephemeral key pair (generated fresh for this session). This key pair is created from scratch for every single TLS connection. Itâs used for the Diffie-Hellman key exchange. After the session ends, itâs destroyed.
The long-term private key does not create the ephemeral keys. The ephemeral keys are generated independently using a random number generator. The long-term private keyâs only job is to sign the ephemeral public key, proving it came from the legitimate server and not from an attacker.
Think of it this way. The long-term key is your passport. It proves who you are. The ephemeral key is a one-time meeting room code. You generate a new code for every meeting. Your passport doesnât create the code. But you sign the code with your passport to prove youâre the one who chose it.
When the cipher suite uses ECDHE, the key exchange happens across two handshake messages: ServerKeyExchange and ClientKeyExchange. The following diagram shows the complete flow:
sequenceDiagram
participant C as Client
participant S as Server
S->>S: 1. Generate ephemeral EC key pair (fresh, random)
S->>S: 2. Sign ephemeral public key with long-term private key
S->>C: 3. ServerKeyExchange (ephemeral public + curve + signature)
C->>C: 4. Verify signature using certificate's public key
C->>C: 5. Generate own ephemeral EC key pair (fresh, random)
C->>S: 6. ClientKeyExchange (client's ephemeral public)
Note over C: 7. pre_master = ECDH(client_ephemeral_private, server_ephemeral_public)
Note over S: 7. pre_master = ECDH(server_ephemeral_private, client_ephemeral_public)
Note over C,S: Both compute the same pre-master secret
Step by step:
Step 1: The server generates a brand new ephemeral EC key pair. This is a random key pair that has never been used before and will never be used again. It has nothing to do with the serverâs long-term certificate key.
Step 2: The server signs its ephemeral public key using its long-term private key (the one that matches the certificate). This signature is the bridge between authentication and key exchange. It proves that the ephemeral key came from the real server.
Step 3: The server sends the ServerKeyExchange message containing the ephemeral public key, the curve name (e.g., X25519), and the signature from step 2.
Step 4: The client verifies the signature using the public key from the serverâs certificate. If the signature is valid, the client knows the ephemeral key genuinely came from the server. If an attacker tried to inject their own ephemeral key, they couldnât produce a valid signature because they donât have the serverâs long-term private key.
Step 5: The client generates its own ephemeral EC key pair. Also fresh, also random, also independent of any long-term key.
Step 6: The client sends its ephemeral public key to the server in the ClientKeyExchange message. No signature needed here because the client doesnât have a certificate in standard (non-mutual) TLS.
Step 7: Both sides independently compute the pre-master secret using the ECDH function. The client combines its ephemeral private key with the serverâs ephemeral public key. The server combines its ephemeral private key with the clientâs ephemeral public key. The math guarantees both arrive at the same value.
After the pre-master secret is computed, the ephemeral private keys are no longer needed. They should be securely erased from memory. This is what makes forward secrecy work.
If an attacker compromises the server tomorrow and steals the long-term private key, they can impersonate the server going forward. But they cannot decrypt past sessions. The ephemeral keys that were used to compute those sessionsâ pre-master secrets are gone. Thereâs nothing left to steal.
This is the fundamental difference between ECDHE and static RSA key exchange. With RSA key exchange, the client encrypts the pre-master secret with the serverâs long-term public key. If that long-term key is ever compromised, every past session can be decrypted. With ECDHE, each sessionâs secret dies with the session.
The client advertises which elliptic curves it supports in the
supported_groups extension of the ClientHello. The server
picks one. Common choices:
Next: Session Resumption