Key exchange: from public values to protected traffic
Algorithm negotiation chooses a key-exchange method. Running that method must then accomplish three different jobs:
- establish fresh secret material over an observable network;
- authenticate the server and the handshake transcript; and
- derive independent keys for protecting packets in both directions.
It does not authenticate the login user. User authentication is a later SSH protocol layered over this protected transport.
This chapter treats cryptographic primitives as black boxes: what goes in, what comes out, and what security role the output plays. The linked standards contain the mathematical and encoding details for deeper study.
Three mechanisms, three questions
Key exchange has three separate jobs.
| Mechanism | Question it answers |
|---|---|
| Ephemeral key agreement | Can both endpoints derive secret material that a passive observer cannot? |
| Host-key signature | Did the holder of this host key approve this exact handshake? |
| Host-key trust policy | Is this key authorized to represent the host the user intended to reach? |
Passing the first two checks is not enough if the client accepts any host key. An active attacker can run its own key exchange and sign its own transcript with its own key. The client’s known-hosts or certificate policy supplies the missing identity binding.
The basic signed key-exchange flow
Many SSH KEX methods fit the same two-message shape after KEXINIT:
sequenceDiagram
participant C as Client
participant N as Untrusted network
participant S as Server
C->>N: Client ephemeral public value Q_C
N->>S: Q_C
Note over C: Keep ephemeral private value q_C
Note over S: Generate q_S and Q_S
S->>N: Host public key K_S, Q_S, signature over H
N->>C: K_S, Q_S, signature over H
Note over C,S: Independently derive the same shared secret K
Note right of C: Rebuild H, validate K_S, verify signature
The public values are safe to expose. The ephemeral private values and the resulting shared secret are not transmitted. “Ephemeral” means freshly generated for this exchange and discarded afterwards. Compromise of the server’s long-term host private key at a later date should therefore not reveal old traffic secrets; this property is called forward secrecy.
The server host key serves a different lifetime and purpose. It is normally persistent so clients can recognize the server across connections, and its private half signs the exchange hash.
Key agreement is method-specific
The negotiated method defines how the endpoints exchange public material,
validate peer inputs, and derive the shared secret K. Finite-field
Diffie–Hellman, ECDH, and post-quantum hybrid methods use different messages
and checks, but they feed the same later SSH stages: compute the exchange hash,
verify the host-key signature, and derive traffic keys.
The protocol invariant is exactness. Each endpoint must follow the selected method’s wire encodings and reject invalid public values. It must not import validation rules from a similar-looking method.
The optional Key-exchange method survey compares fixed-group DH, group exchange, ECDH, X25519, and standardized hybrid methods.
The exchange hash: authenticate the whole decision
Deriving the same secret is not enough. The client must know that an attacker
did not alter the version strings, proposals, host key, or ephemeral values.
SSH serializes those values and hashes them into the exchange hash H.
For the classic DH flow in RFC 4253, the conceptual inputs are:
H = HASH(
V_C || V_S ||
I_C || I_S ||
K_S ||
e || f ||
K
)
Where:
V_C,V_Sare the identification lines without CRLF;I_C,I_Sare the exactKEXINITpayloads, starting with their message number;K_Sis the encoded server public host key;e,fare the client and server ephemeral public values; andKis the shared secret.
This is conceptual notation rather than raw byte-array concatenation. Each item
uses the SSH wire type required by that KEX specification. ECDH,
group-exchange, and hybrid methods adjust the method-specific fields, so H
has a method-specific wire definition even though its security role is stable.
Because the proposals are included, an attacker cannot silently delete a
stronger shared algorithm from the lists to force a weaker mutual choice. The
server and client would hash different KEXINIT payloads and signature
verification would fail.
The host-key signature and the trust decision
The server signs H with its host private key. The client verifies the
signature using K_S, the public host key carried in the reply. This proves
that one entity controlled both the KEX response and the private key matching
K_S.
The client must then establish that K_S is acceptable for the intended host,
for example by:
- matching a previously pinned key in a known-hosts database;
- validating an SSH host certificate under a trusted certification key; or
- asking a user to verify a fingerprint through an independent channel.
Skipping or merging these two gates causes security bugs. A valid signature made by an attacker’s own key is still a valid signature; it is not evidence that the key belongs to the requested server. The two checks may occur in either order, but both properties are required for an authenticated KEX.
From K and H to traffic keys
The KEX method outputs the shared secret K and exchange hash H. The base
SSH key schedule combines them with a one-byte purpose label and the session
identifier to produce separate key material:
flowchart LR
K[Shared secret K] --> KDF[SSH key derivation]
H[Current exchange hash H] --> KDF
SID[Session identifier] --> KDF
KDF --> A[Initial IV C→S]
KDF --> B[Initial IV S→C]
KDF --> C[Encryption key C→S]
KDF --> D[Encryption key S→C]
KDF --> E[Integrity key C→S]
KDF --> F[Integrity key S→C]
In RFC 4253, Section
7.2, labels A through
F distinguish those outputs. If a cipher needs more key bytes than one hash
produces, the specified expansion procedure produces more. Modern combined
cipher-and-integrity constructions may consume the categories differently;
the negotiated method defines that mapping.
Independent directional keys prevent a packet sent in one direction from being replayed as if it came from the other and keep each direction’s cipher state separate.
Session identifier versus exchange hash
On the first KEX:
session_id = H_first
On a rekey, a new exchange produces fresh K and a new H, but
session_id remains H_first for the entire SSH connection.
timeline
title Exchange hashes and one stable session identifier
Initial KEX : H1 calculated
: session_id = H1
: keys derived from K1, H1, session_id
Rekey 1 : H2 calculated
: session_id remains H1
: keys derived from K2, H2, session_id
Rekey 2 : H3 calculated
: session_id remains H1
: keys derived from K3, H3, session_id
The stable identifier binds later protocols—most notably public-key user
authentication—to this SSH connection even as its transport keys change. The
latest H never replaces it.
Activating keys with SSH_MSG_NEWKEYS
Key derivation alone does not define the byte at which an endpoint should
switch algorithms. SSH_MSG_NEWKEYS is the boundary marker, independently for
each direction.
- Immediately after sending
NEWKEYS, use the new algorithms and keys for subsequent outbound packets. - When receiving
NEWKEYS, use the new algorithms and keys for subsequent inbound packets.
sequenceDiagram
participant C as Client
participant S as Server
Note over C,S: KEX packets use the old protection<br/>(none during initial KEX)
C->>S: NEWKEYS (old outbound protection)
Note left of C: Switch C→S sending keys
S->>C: NEWKEYS (old outbound protection)
Note right of S: Switch S→C sending keys
C->>S: First packet under new C→S keys
S->>C: First packet under new S→C keys
The messages may cross on the network, creating a brief interval in which one
direction uses new keys while the other still uses old keys. Under strict KEX,
each direction’s packet sequence number is also reset just after its
corresponding NEWKEYS boundary.
Only after key activation can extension information and higher-layer service requests proceed in the newly protected transport. See RFC 4253, Section 7.3 and RFC 8308 for the post-KEX extension exchange.
Rekeying a live connection
SSH can repeat key exchange without opening a new TCP connection or repeating
user authentication. Either endpoint starts a rekey by sending a new
SSH_MSG_KEXINIT; the other responds with its proposal.
Why rekey?
- limit how much traffic is protected by one set of keys;
- replace keys after an endpoint-defined time or byte count;
- negotiate a new algorithm policy that both endpoints now offer; or
- refresh the cryptographic state of a long-lived connection.
RFC 4253 recommends rekeying after one gigabyte or one hour, whichever comes first. This is a default recommendation, not a universal limit. Endpoints may use stricter policy, and selected algorithms can impose stricter limits.
During rekey:
- the KEX packets are protected by the old algorithms until each directional
NEWKEYStransition; - client and server roles do not change;
- fresh
KandHvalues are produced; - the original session identifier does not change; and
- higher-layer application traffic pauses once KEX is in progress, apart from already in-flight packets allowed by the protocol state machine.
A peer can receive an arbitrary number of application packets that were
already in flight before it sees the other side’s KEXINIT. This is why the
rekey transition is not an instantaneous, connection-wide boundary.
sequenceDiagram
participant C as Client
participant S as Server
C->>S: CHANNEL_DATA under old keys
S->>C: KEXINIT under old keys
Note over C: An application packet may already be in flight
C->>S: KEXINIT under old keys
Note over C,S: Pause new application messages<br/>and run KEX under old protection
C->>S: NEWKEYS under old C→S keys
S->>C: NEWKEYS under old S→C keys
Note over C,S: Resume with fresh directional keys
Crossed NEWKEYS messages, simultaneous KEX initiation, and application data
already in flight all follow from the two independent directions shown above.
Security invariants
The essential invariants across initial KEX and rekey are:
- ephemeral private values are unpredictable and are never sent;
- received public values have the exact encoding, length, group membership, and special-value checks required by the selected method;
- the exchange hash uses exact on-wire transcript values and type encodings;
- host signature validity and host identity trust are distinct properties;
- key derivation produces independent material for both directions;
- sending and receiving switch keys at their own
NEWKEYSboundaries; - the session identifier is assigned once, from the first
H; - a rekey retains roles and the session identifier but replaces traffic keys.
Check your understanding
- Which key is usually persistent: an ephemeral ECDH key or a server host key?
- What does a valid signature over
Hprove, and what does it not prove by itself? - Why are both
KEXINITpayloads included inH? - Why must public-value validation follow the selected method’s rules?
- The client has sent
NEWKEYSbut has not received the server’sNEWKEYS. Which new keys are active? - Does the session identifier change after rekeying?
Answers
- The server host key. Ephemeral ECDH keys are freshly generated for a KEX.
- It proves that the holder of the private key corresponding to
K_Sapproved that exchange hash. A separate trust check establishes whetherK_Srepresents the intended host. - To bind algorithm negotiation into the authenticated transcript and detect modification or downgrade.
- Methods use different encodings, groups, and invalid-value checks. A value accepted under another method’s rules may be unsafe or malformed here.
- New keys are active for the client’s outbound direction. Its inbound
direction still uses the old keys until it receives server
NEWKEYS. - No. It remains the first exchange hash for the life of the connection.
Primary references
- RFC 4253 — SSH Transport Layer Protocol, Sections 7–9.
- RFC 8308 — Extension Negotiation in SSH.
- Key-exchange method survey — optional details and method RFCs.