TLS 1.3 encrypts most handshake messages after ServerHello, but the initial ClientHello is sent before those handshake keys exist. That leaves fields in the first flight visible to an observer on the network. Server Name Indication (SNI) is especially revealing because it can identify the requested service even when the later certificate and application traffic are encrypted.

RFC 9849 defines Encrypted Client Hello (ECH) to narrow that exposure. ECH does not encrypt the entire first packet. It constructs two ClientHello messages with different roles: a private ClientHelloInner containing the connection parameters intended for the backend, and a public ClientHelloOuter that carries an encrypted representation of the inner message.

The inner message carries the private handshake intent

A client with a compatible ECHConfig first builds ClientHelloInner much like a normal TLS 1.3 ClientHello. Sensitive values, including the true server name, belong there. The client then encodes that message and encrypts it with Hybrid Public Key Encryption (HPKE) using the public key and algorithms described by the selected ECH configuration.

The resulting ciphertext is placed in the encrypted_client_hello extension of ClientHelloOuter. The outer message remains visible because a client-facing server must receive and parse it before it can recover the inner message.

This split creates a precise privacy boundary:

network observer
      |
      v
ClientHelloOuter
  public SNI
  visible outer extensions
  encrypted_client_hello = HPKE(ClientHelloInner)
                               |
                               v
                         true SNI + private parameters

ECH therefore protects information placed in the inner message; it does not make every property of connection establishment opaque.

ECHConfig supplies the encryption parameters

ECH depends on configuration delivered to the client before the protected handshake. An ECHConfig includes an HPKE public key, a configuration identifier, supported cryptographic choices, and a public_name used for the externally visible handshake.

RFC 9849 defines the configuration format and leaves DNS publication to the SVCB and HTTPS record mechanisms specified for ECH advertisement. A client can also obtain configuration through another trusted delivery mechanism.

Possessing a configuration is not equivalent to possessing the private key. The client needs only the public material to encrypt. The client-facing server needs the corresponding private key to decrypt the inner message.

Configuration freshness matters operationally. If a client uses a key the server no longer accepts, decryption can fail even though the service currently supports ECH. The protocol therefore includes a controlled path for supplying retry configurations.

The outer message is an envelope, not a decoy packet

ClientHelloOuter is a syntactically valid ClientHello and participates in the rejection path. It can contain a public SNI derived from the ECH configuration’s public_name, along with values suitable for the externally visible endpoint.

The encrypted payload is not detached from that outer context. RFC 9849 authenticates ClientHelloOuter as associated data in the HPKE operation. Conceptually, the encryption binds the private message to the relevant outer handshake fields rather than treating the ciphertext as a freely movable blob.

Some extensions may be duplicated between inner and outer messages. ECH also defines ech_outer_extensions, allowing selected outer extension values to be referenced while reconstructing the inner message. The reconstruction rules reject missing, repeated, reordered, or otherwise invalid references. Those checks keep extension compression from becoming an unconstrained transformation.

Acceptance changes which ClientHello drives TLS

After a client-facing server decrypts a valid ECH payload, it reconstructs ClientHelloInner and processes or forwards that inner message for the TLS handshake. The backend behaves as though the inner message were the ClientHello. Its preferences and transcript contribution, rather than the public envelope, govern the accepted ECH handshake.

The client also needs authenticated evidence that the server accepted ECH. RFC 9849 defines acceptance confirmation derived from handshake state. For a normal ServerHello, the confirmation occupies the final eight bytes of ServerHello.random. A HelloRetryRequest uses a dedicated confirmation value in its ECH extension.

This signal is security-relevant. A client cannot safely infer acceptance merely because it sent an encrypted payload or because the server continued the handshake.

Rejection is not silent permission to send application data

A server that cannot decrypt ECH can proceed using ClientHelloOuter; this is called ECH rejection. That behavior supports GREASE and configuration recovery without making an unrecognized ECH extension fatal at the server.

The client applies stricter semantics. When a real ECH attempt is rejected, the outer connection is not used for application data. If the server provides valid retry configurations through the defined mechanism, the client can establish a new connection using current configuration.

This separation matters for downgrade resistance. A network attacker must not be able to strip or corrupt ECH and cause the client to quietly continue to the private target over an ordinary exposed handshake. Failure and retry handling are part of the privacy property, not merely compatibility behavior.

Outer fields and traffic shape still expose information

ECH protects the encoded inner ClientHello, but the outer message remains observable. Any sensitive value copied into ClientHelloOuter defeats protection for that value. RFC 9849 accordingly warns clients against placing server-specific private information in outer extensions.

Length can also disclose structure. The encrypted payload length reflects the encoded inner message unless padding reduces that signal. ECH defines padding for EncodedClientHelloInner, but other observable behavior can still create distinctions among services.

The privacy goal is framed around an anonymity set: co-located servers need sufficiently consistent externally visible TLS configuration and behavior for connections to resist distinction. Extension ordering, record boundaries, response behavior, timing, IP routing, and other side channels are not erased merely by encrypting SNI.

ECH is therefore not a general traffic-analysis defense. It protects a defined set of handshake metadata while leaving transport and deployment characteristics subject to separate controls.

Split deployments create a second trust boundary

ECH supports a client-facing server in front of a backend server. The front end holds the ECH decryption capability, recovers ClientHelloInner, and forwards the resulting handshake to the appropriate backend.

That architecture reduces metadata exposed on the client-to-edge path, but it does not make the recovered inner message secret from the client-facing server. Operators need to treat ECH private keys, front-end processing, and the path between front end and backend as security-sensitive components.

Sharing one ECH private key across a broad fleet also expands the impact of that key’s compromise. RFC 9849 permits operators to partition keys and rotate configurations; the suitable boundary depends on the deployment rather than on a universal topology.

ECH narrows one exposed part of TLS

The useful security claim is deliberately bounded. ECH encrypts ClientHelloInner, including SNI and other sensitive extensions placed there, and binds that encrypted content to the public outer handshake. Acceptance confirmation and retry rules prevent ordinary rejection from becoming an invisible downgrade path.

It does not conceal the destination IP address, make all outer fields private, hide every size or timing signal, or replace normal TLS certificate authentication. Its value comes from removing sensitive handshake metadata from passive view while retaining explicit protocol behavior when configuration is stale, unsupported, or rejected.