Encrypted Client Hello: Closing TLS’s Last Big Privacy Gap

Modern Internet traffic is almost universally encrypted, but that protection applies to the payload—the actual content of communication—not to the metadata surrounding it. Before two endpoints can exchange encrypted data, they must first negotiate an encryption key. That negotiation happens during the Transport Layer Security (TLS) handshake, and for most connections, a significant portion of this handshake is transmitted in plaintext.

This plaintext portion leaks a surprising amount of information. Network observers can see the identities of the endpoints, how the connection is used, and most notably the Server Name Indication (SNI), which reveals exactly which server a client is trying to reach. The SNI leak has long been one of the most persistent privacy weaknesses in TLS, effectively defeating the anonymity protections of encrypted DNS.

Encrypted Client Hello (ECH), a new TLS extension under development in the IETF, aims to fix this by encrypting the entire client handshake message. This goes beyond merely protecting the SNI—which is its most visible benefit—by also creating a foundation for future TLS enhancements that would otherwise introduce new metadata leaks. Any future feature added to the handshake would inherit ECH’s privacy protections automatically.

ECH is the result of collaboration between academics and industry players including Cloudflare, Fastly, and Mozilla, facilitated by the IETF working group process. It builds on related privacy technologies, such as DNS-over-HTTPS, that are only now beginning to see real-world deployment. The protocol is still evolving and not yet ready for production at Internet scale, so this description reflects the current state of the design.

The Problem: Metadata Leaks at Every Layer

Network observers can learn a surprising amount about a TLS connection without ever decrypting its content. The handshake that sets up the connection carries not only the SNI but also the client’s list of supported cryptographic algorithms, extensions, and other parameters—all in the clear. This data reveals what kind of client is connecting, which can be used to fingerprint the device and operating system.

In many cases, merely knowing the SNI is enough to identify the user or organization behind a connection, since hostnames themselves are often sensitive. Protecting the SNI by encrypting it in the Client Hello closes this informational channel, making it less clear what clients are connecting to.

ECH is designed to be a defense-in-depth measure rather than a complete anonymity solution. Even with the handshake fully encrypted, an observer can still see IP addresses, TCP ports, DNS queries prior to connection setup, and the mere fact that a TLS connection is happening. ECH is specifically about making content and metadata invisible after the initial TCP connection is established—not about hiding the existence of the connection itself.

How ECH Works in Practice

The operation ECH is based on a hybrid key exchange mechanism. The client sends part of its key share to a TLS terminator, then the server’s key share is encrypted, and afterwards the client gets the full key share in return. This is enough to bootstrap the entire handshake.

ECH is implemented as an extension within the Client Hello message. When the client sends a Client Hello that includes an ECH extension, it will first generate an ephemeral key pair for the connection. The client will use the server's public key published in DNS to encrypt what is called the inner Client Hello—which contains the true SNI and other sensitive values.

A significant design decision is how ECH handles the failure mode where the client tries to talk to a server that doesn’t support ECH. If the server doesn’t recognize the ECH extension, the outer Client Hello is forwarded to the origin server as a regular TLS connection, and the client’s encrypted inner Client Hello is never processed. The client then retries without ECH extension, alerting the origin server that a connection attempt was made.

This arrangement creates an interesting proxy: to an observer, the Client Hello is associated with the TLS terminator’s IP address rather than the origin’s, so the observer cannot link a client to a particular website by looking at the handshake. Instead, an observer only knows that the client is attempting to connect to the TLS terminator.

Unpacking the SNI: Why It Matters

The SNI is the single most revealing part of a TLS Client Hello. Every major website that uses TLS or CDN services will typically use SNI to let the server deliver the correct certificate. The problem is that this field is sent literally in the clear. Any network observer—an ISP, a malicious actor on a Wi-Fi network, a government—can simply read the Server Name Indication.

Good-bye ESNI, hello ECH! Embedded Image - g9qRj6

The result is that a user’s SNI is then transmitted in plaintext to any observer located between the client and the server.

Good-bye ESNI, hello ECH! Embedded Image - DE3pvN

Through ECH, the client and server can exchange the SNI via the encrypted portion of the handshake via a publicly known key. ECH therefore prevents an observer from capturing and replaying the server’s key to strip the encryption. This is achieved by adding an authenticated encryption around the inner Client Hello that prevents an observer from forging or replaying keys, while also ensuring the server can prove the origin of the handshake.

A client that does not support ECH appears exactly like a client that does support ECH to an observer, since by design the outer Client Hello contains only the Client Hello of a client that doesn’t support ECH. This is the basis of protection of the user’s privacy against non-participating servers.

What Comes Next

ECH is a critical privacy enhancement, but deployment involves significant coordination. A server needs to publish a public key in DNS for ECH to work, which requires distributed infrastructure for key management and rollover. The design also depends on the deployment of DNS-over-HTTPS and DNS-over-TLS, because without those technologies the client’s DNS queries would leak its intended destination anyway.

In the background, work is being done to build a single well-known ECH key that could be shared among parties, so that a single DNS lookup is sufficient to communicate with any ECH-enabled service.

The TLS ecosystem is mature and battle-tested, but it is also conservative—major changes are introduced only after careful review. ECH’s path toward standardization involves iterating on draft specifications while collaborating with organizations like Mozilla and Fastly to test compatibility. The promise is that a future Internet-wide rollout of ECH makes the TLS handshake itself an encrypted channel for metadata, which is possibly the most meaningful privacy upgrade since TLS was created. It closes the last significant metadata leak on the protocol.

Why the ClientHello Is Still Visible

The TLS handshake has always been a negotiation of far more than just keys. Protocol version, cipher suites, authentication methods, and the application-layer protocol to run after the handshake are all on the table. Each of these parameters carries security implications, and some carry privacy implications as well.

The Server Name Indication (SNI) extension is the clearest example. SNI lets a client tell a TLS-terminating server which website it wants, which is how a single operator can host many origins behind one IP address and still present the correct certificate. But that convenience comes at a cost: any network observer can read the SNI and learn exactly which origin the client is contacting. Other handshake parameters leak too. The Application-Layer Protocol Negotiation (ALPN) extension, for instance, reveals whether the client intends to speak HTTPS, email protocols, instant-messaging protocols, or something else entirely.

Some proposed TLS enhancements are privacy-sensitive enough that their unprotected inclusion is a non-starter. Password-authenticated key exchange (PAKE) is one such idea. PAKE would let TLS authenticate with a password instead of (or alongside) certificates, but the client would need to send a username or email address to the server during the handshake so the server could fetch the right credentials. Without encryption, that personally identifiable information would be plaintext on the wire.

The common thread is handshake encryption: encrypting TLS handshake messages beyond just application data. The obvious difficulty is bootstrapping. The handshake itself is how the client and server arrive at a shared key, so some parameters must remain in cleartext to establish that key. ECH's goal is to encrypt everything in the handshake except those strictly necessary parameters.

Encrypting the Handshake so Far

Prior to TLS 1.3, no part of the handshake was encrypted. The IETF's push to counter mass surveillance following the 2013 Snowden disclosures made handshake encryption a stated goal of the TLS 1.3 effort when standardization began in 2014. The final standard (RFC 8446, published in 2018) nevertheless leaves several parameters, including SNI, in the clear.

TLS 1.3 encrypts the handshake only after the client and server have exchanged key shares in the ClientHello and ServerHello and derived a shared secret. From that point on, handshake messages are encrypted with the handshake traffic key, and application data is encrypted separately with the application traffic key. The first encrypted message in the handshake is the server's EncryptedExtensions, which is where server-side sensitive parameters like its ALPN selection now live.

Everything the client sends, sensitive or not, arrives in the ClientHello. One could imagine reworking the message flow to encrypt more of the client's early messages, but the problem is a chicken-and-egg one. The client has no reason to encrypt anything before it verifies the server's certificate and the server's possession of the shared secret. Those authentication steps prevent monster-in-the-middle attacks, where the attacker masquerades as the server and decrypts client traffic. But SNI must reach the server before that authentication completes, because the server needs SNI to pick which certificate to present.

Confidentiality for authentication-critical handshake parameters requires that the client and server already share a key. The question is where that key comes from.

Full handshake encryption was actually part of early TLS 1.3 drafts. In draft-10 (circa 2015), the server would present a long-lived public key during an initial handshake that the client could use to encrypt its messages in later handshakes. This design, borrowed from the OPTLS protocol and the original QUIC proposal, was known as 0-RTT. Its primary motivation was permitting the client to send application data before the handshake completed, but a side benefit would have been encrypting the client's own sensitive handshake parameters in subsequent connections.

0-RTT did not survive to the final TLS 1.3 specification. Its complexity outweighed its utility in the eyes of the standard's authors, and crucially, it would have done nothing for the very first handshake, when the client still needed a clear SNI to get the server's certificate. Nonetheless, 0-RTT is the forerunner of mechanisms like ECH that use public-key encryption to protect ClientHello parameters. The central challenge for all such schemes is key distribution.

ESNI: A First Step with a Fatal Flaw

Encrypted SNI (ESNI) was the direct predecessor to ECH. As its name states, its scope was limited to the SNI extension. The client would encrypt SNI under the server's advertised public key, and the server would decrypt it. If decryption succeeded, the handshake proceeded with the decrypted name; if not, the handshake aborted.

ESNI key distribution leaned on DNS. A client looking for the ESNI key for crypto.dance would issue a TXT query for _esni.crypto.dance alongside its usual A/AAAA lookups, and the response would carry a base64-encoded blob containing the public key and associated parameters like the encryption algorithm.

Encrypting SNI while merrily sending DNS queries in plaintext would obviously defeat the purpose. ESNI found a practical path with DNS-over-HTTPS (DoH), which encrypts queries between the client and the DoH resolver. DoH also provides authenticity for the retrieved ESNI keys, protecting against a local attacker who might try to poison DNS caches, strip ESNI from responses, or substitute a key under the attacker's control.

ESNI was a real deployment, not a paper design. Cloudflare made it available in 2018, and Firefox users could enable it on an opt-in basis. Operational experience exposed the protocol's reliance on DNS as its weak underbelly. Cloudflare rotated ESNI keys hourly to limit damage in case of compromise, but DNS caches live far longer than an hour. Stale keys were common, and while the deployment tolerated that to a degree, keys must eventually expire. ESNI never answered what a client should do when decryption fails and the current key is unavailable through DNS or any other means.

Another structural issue: the DNS records that point a client to an origin and the DNS records that carry the ESNI key are not atomically linked. If example.com resolves to multiple IP addresses operated by different CDNs, the _esni.example.com TXT record can only carry one of their keys. A client might offer an ESNI extension to an endpoint that has no matching private key, and the handshake would simply fail. Fixing this coordination problem requires DNS protocol changes.

The ESNI Design and Its Attacks

ESNI's flow differed from a plain TLS 1.3 handshake only in that the SNI extension was replaced by its encrypted form. The design turned out to have theoretical weaknesses beyond its practical DNS limitations. Several attacks were catalogued in later ESNI drafts that are complicated to mount but point squarely at fundamental gaps in the protocol.

One of the design pressures leading to ECH came out of ESNI's incomplete coverage: it was only SNI that got protected. The ALPN list and all other privacy-relevant client parameters went out in the clear. The next iteration needed to encrypt more than just the server name.

Cloudflare has indicated it will keep ESNI active until ECH matures to production quality, regarding the former still as a meaningful privacy improvement today.

How ECH differs from ESNI

TLS 1.3 and ESNI left one gap open: the bulk of the ClientHello, including privacy-sensitive parameters beyond SNI, was still transmitted in cleartext. ECH closes that gap by encrypting the entire ClientHello. The protocol builds on the same basic idea as ESNI — a public key distributed via DNS and fetched over DoH is used to encrypt the client’s first flight — but it improves the key distribution mechanism to be resilient against DNS cache inconsistencies.

Whereas ESNI required the server to abort the connection when decryption failed, ECH handles failure more gracefully. When decryption fails, the server completes the handshake anyway and supplies the client with the correct public key so it can retry. This is possible because ECH involves two ClientHello messages rather than one. The ClientHelloOuter is sent in cleartext as usual. The ClientHelloInner, which carries the client’s intended handshake parameters, is encrypted and embedded as an extension of the outer message.

Good-bye ESNI, hello ECH! Embedded Image - db1FU3

Figure 3: The TLS 1.3 handshake with the ECH extension.

If the server can decrypt the inner ClientHello, it proceeds with the parameters found there. If not, it proceeds with the outer ClientHello. In that case, the handshake completes against the ECH service provider — called the client-facing server — and the client immediately aborts the connection and retries with the key provided in the server’s response.

The ClientHelloInner contains the real SNI of the origin server (the backend server), the ALPN list, and any other parameters that would guide post-handshake behavior. The ClientHelloOuter must itself be a valid ClientHello with at minimum the parameters required for a server-authenticated key exchange, but it is not used for the actual connection. It also contains an SNI value, which the client expects to match the client-facing server in case decryption fails.

Dependencies and design context

ECH’s design draws on the broader IETF ecosystem. Two standards in particular are necessary for its success. The first is the HTTPS resource record type in DNS, which allows multiple HTTPS endpoints authoritative for the same domain name to advertise different TLS capabilities. This makes DNS viable as a key distribution channel and addresses a deployment problem that ESNI encountered. The second is the CFRG’s Hybrid Public Key Encryption (HPKE) standard, which provides an extensible framework for public key encryption. ECH delegates the details of its handshake encryption to HPKE, which simplifies the specification and makes it easier to analyze.

Open challenges

The protocol’s overall design is fairly stable; the next draft will be the first targeted for interoperability testing among implementations. Several details remain unresolved.

Resistance to traffic analysis

The aim of ECH is to make connections to different origin servers behind the same ECH service provider indistinguishable to network observers. Encrypting the ClientHello is an important step, but it is not sufficient on its own. Traffic analysis — the collection and analysis of channel properties such as ciphertext length — can still leak information. A short or long domain name in the encrypted SNI might be guessable from the length of the encrypted ClientHello. The current specification includes some mitigations, but their coverage is incomplete, and hardening against traffic analysis is a direction for future work.

Network ossification

TLS 1.3 deployment taught us that core protocol changes can trigger unexpected failures when middleboxes — network appliances that monitor and sometimes intercept traffic — lack the capacity to handle traffic that does not match their expectations. When browsers first enabled TLS 1.3 experimentally, Cloudflare and others observed connection failure rates significantly higher than with TLS 1.2. The problem was widespread enough that TLS 1.3’s design was adapted to make it resemble TLS 1.2 on the wire, which empirically reduced failures enough to make deployment viable.

ECH faces a similar risk. ClientHello fields like SNI have long been visible, and the impact of encrypting them is not yet known. The protocol’s design minimizes the difference from a standard TLS 1.3 handshake: the main distinguishing feature is the ECH extension itself, which compliant middleboxes should ignore. Whether that proves sufficient for wide-scale deployment remains to be seen. If ECH succeeds, it may help reduce ossification pressure on future TLS changes, since encrypting the full handshake leaves fewer visible protocol features for middleboxes to depend on.