Resources

Encrypted ClientHello (ECH)

TLS encrypts the HTTP request and response, but the traditional TLS handshake still exposes the name of the website in the Server Name Indication. Encrypted ClientHello closes that gap by placing the real ClientHello inside an encrypted inner message and showing a shared public name on the network instead.

The short version: only an ECH accepted result proves that the ClientHello observed on that web connection was protected. Seeing an ECH extension is not enough: it may be GREASE, stale, or encrypted to a key the server does not hold.

The Remaining Privacy Gap in TLS

A browser needs to tell a TLS server which site it wants before the server can select the right certificate and application protocol. Traditionally it does that in the server_name extension of its first TLS message, the ClientHello. This happens before the normal TLS encryption keys have been established.

A passive observer may therefore be unable to read the page, its URL path, cookies or form data, yet still learn which hostname the browser visits. The destination IP address is also visible, but it is often shared by many sites behind a CDN or other edge service. The cleartext server name can remove that ambiguity.

ECH, standardized in RFC 9849, encrypts the sensitive ClientHello rather than only the SNI field. That distinction matters because TLS parameters other than the hostname can also identify or fingerprint a client.

One Connection, Two ClientHellos

An ECH-capable client constructs two related messages. The public ClientHelloOuter is sent on the wire. Its ECH extension carries an encrypted ClientHelloInner, which is the message used for the real TLS connection when the server accepts ECH.

MessageWhat it is forWhat it contains
ClientHelloOuter Visible transport envelope A shared public name, innocuous TLS parameters and the encrypted ECH payload. Some non-sensitive extensions may be duplicated or referenced by the inner message.
ClientHelloInner The real TLS handshake The origin SNI and the TLS preferences that the server uses after decrypting and accepting ECH.

The public name is not a disguised spelling of the origin name. It identifies the client-facing ECH service and may be shared by many origins. The privacy set is the group of origins using that service and ECH configuration. The larger and less distinguishable that set is, the less the public name reveals.

How the Client Learns the ECH Key

The client needs the ECH service's public key before it sends the first TLS message. RFC 9848 carries the configuration in the ech parameter of a DNS HTTPS or SVCB record:

example.test.  IN  HTTPS  1 . alpn="h3,h2" ech="AEj+DQBEAQAg..."

The encoded value contains the public name, an HPKE public key and the algorithms the client may use. It is configuration for the TLS connection, not a TLS session key. The private ECH key remains on the server.

DNS is therefore part of the ECH security story. If the lookup travels in cleartext, an observer may read the origin name from DNS before ECH hides it in TLS. Encrypted DNS such as DoH, DoT or DoQ protects the client-to-resolver leg. The recursive resolver still learns the name, and its own query to an authoritative nameserver is a separate leg with separate privacy properties.

For a detailed explanation of HTTPS records and their other parameters, see DNS HTTPS Records and Alt-Svc.

Acceptance, Rejection, Retry and GREASE

A server that owns the matching ECH private key decrypts the inner message and signals acceptance inside the TLS handshake. The client verifies that signal. This prevents a middlebox from guessing the hidden hostname and pretending that it accepted the inner handshake.

If the server cannot decrypt the payload, it rejects ECH and continues temporarily with the outer ClientHello and public name. That outer connection is used only to authenticate the public ECH service and recover. It is not usable for application data. The client aborts it and may retry with an updated configuration supplied by the server, or retry without ECH if the authenticated server has securely indicated that ECH is unavailable.

ECH-capable clients may also send a realistic-looking but deliberately undecryptable ECH extension when they have no configuration. This is called GREASE ECH. It prevents an observer from identifying real ECH use merely by checking whether the extension exists. A server cannot reliably distinguish GREASE from a foreign or stale configuration just from the failed decryption.

TestCenter valueMeaning on the observed web connection
acceptedThe server decrypted the inner ClientHello and confirmed acceptance.
undecryptedAn ECH extension arrived but could not be decrypted: commonly GREASE, an unknown configuration or a stale key.
noneNo ECH extension arrived, not even GREASE.
offThe TLS listener that handled the connection was not serving ECH.

What ECH Protects—and What It Does Not

ECH protects:

  • the real SNI and the other sensitive contents of the inner ClientHello;
  • the distinction between origins sharing the same ECH service, subject to the size and quality of that anonymity set;
  • the handshake from a middlebox that tries to substitute guessed inner parameters.

ECH does not hide:

  • the destination IP address, port, public name, packet sizes or timing;
  • the DNS name from a resolver receiving the client's query;
  • the origin from the ECH server itself, which must decrypt the inner ClientHello;
  • information that can be inferred through traffic analysis or a very small anonymity set.

What Changes with an SSE Gateway

A TLS-inspecting gateway creates two independent TLS connections: one from the browser to the gateway and one from the gateway to the origin. ECH is therefore also negotiated independently on the two legs.

If DNS directs the browser to the gateway but passes through an ECH configuration belonging to the origin, the gateway cannot accept that inner handshake. Knowing the intended hostname through policy or an earlier DNS observation does not provide the private ECH key or the cryptographic acceptance signal.

An inspecting architecture has three broad choices:

  • Suppress ECH: remove the ech parameter and continue with a cleartext ClientHello. Inspection works, but the privacy improvement is lost.
  • Bypass inspection: preserve the origin's records and let the browser connect directly with origin ECH.
  • Participate in ECH: publish the gateway's ECH configuration for the inspected path, decrypt at the authorized policy boundary, and use the origin's ECH configuration again on the upstream connection.

The third option requires DNS and web policy to describe the same path. It is not enough for the gateway to support ECH in isolation; the client must receive an HTTPS record whose addresses, protocols and ECH configuration all belong to the service it will reach.

How to Read the SSE TestCenter Result

The DNS and Web Visibility test creates a fresh hostname, observes the DNS queries that reach the authoritative service and records the ECH outcome of the web connection that reaches the TestCenter.

  • ECH accepted proves that this observed web connection used the published ECH configuration and protected its inner ClientHello.
  • An HTTPS-record query followed by accepted is consistent with the client using the record's ECH configuration. The TestCenter cannot see when the answer reached the browser internally.
  • undecrypted does not prove that the real hostname was protected. It may be GREASE or a configuration this server does not know.
  • none may mean that the client lacks ECH support, ECH is disabled, no usable HTTPS answer reached it, or an intermediary changed the path.

With a TLS-inspecting proxy, the TestCenter normally observes the proxy-to-TestCenter connection. An accepted result then proves upstream ECH on that leg; it cannot prove what happened between browser and proxy. Compare the result with the gateway logs when you need to establish both sides.

Further Reading