ClientHello describes a Step within the TLS Handshake process.

The TLS ClientHello

First message of a TLS handshake is when the Protocol Client initiates a connections to the Protocol Server using a ClientHello.

The message by which the client states its intention to do some SSL/TLS.

Note that "client" is a symbolic role; it means "the party which speaks first". It so happens that in the HTTPS context, which is HTTP-within-SSL-within-TCP, all three layers have a notion of "client" and "server", and they all agree (the TCP client is also the SSL client and the HTTP client), but that's kind of a coincidence.

The ClientHello message contains:

  • the maximum protocol version that the client wishes to support;
  • the ClientHello.random (32 bytes, out of which 28 are suppose to be generated with a cryptographically strong number generator);
  • the "session ID" (in case the client wants to resume a session in an abbreviated handshake, see below);
  • the list of "Cipher Suites" that the client knows of, ordered by client preference;
  • the list of compression algorithms that the client knows of, ordered by client preference;
  • some optional extensions.

TLS 1.3#

When a client first connects to a server, it is REQUIRED to send the ClientHello as its first message. The client will also send a ClientHello when the server has responded to its ClientHello with a HelloRetryRequest. In that case, the client MUST send the same ClientHello (without modification) except:
  • If a "key_share" extension was supplied in the HelloRetryRequest, replacing the list of shares with a list containing a single KeyShareEntry from the indicated group.
  • Removing the "early_data" extension (Section 4.2.9) if one was present. Early data is not permitted after HelloRetryRequest.
  • Including a "cookie" extension if one was provided in the HelloRetryRequest.
  • Updating the "pre_shared_key" extension if present by recomputing the "obfuscated_ticket_age" and binder values and (optionally) removing any PSKs which are incompatible with the server's indicated Cipher Suite.

Because TLS 1.3 forbids TLS Renegotiation, if a server has negotiated TLS 1.3 and receives a ClientHello at any other time, it MUST terminate the connection.

If a server established a TLS connection with a previous version of TLS and receives a TLS 1.3 ClientHello in a renegotiation, it MUST retain the previous protocol version. In particular, it MUST NOT negotiate TLS 1.3.

Structure of this message:#

uint16 ProtocolVersion;
    opaque Random[32];
    uint8 CipherSuite[2];    /* Cryptographic suite selector */

      struct {
          ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
          Random random;
          opaque legacy_session_id<0..32>;
          CipherSuite cipher_suites<2..2^16-2>;
          opaque legacy_compression_methods<1..2^8-1>;
          Extension extensions<8..2^16-1>;
} ClientHello;

legacy_version In previous versions of TLS, this field was used for version negotiation and represented the highest version number supported by the client. Experience has shown that many servers do not properly implement version negotiation, leading to "version intolerance" in which the server rejects an otherwise acceptable ClientHello with a version number higher than it supports. In TLS 1.3, the client indicates its version preferences in the "supported_versions" extension (Section 4.2.1) and the legacy_version field MUST be set to 0x0303, which is the version number for TLS 1.2. (See Appendix D for details about backward compatibility.)

random 32 bytes generated by a secure random number generator. See TLS 1.3 Appendix C for additional information.

legacy_session_id - Versions of TLS before TLS 1.3 supported a "session resumption" feature which has been merged with Pre-Shared Keys in this version (see Section 2.2). This field MUST be ignored by a server negotiating TLS 1.3 and MUST be set as a zero length vector (i.e., a single zero byte length field) by clients that do not have a cached session ID set by a pre-TLS 1.3 server.


legacy_compression_methods - TLS Versions before TLS 1.3 supported TLS Compression with the list of supported TLS Compression methods being sent in this field. For every TLS 1.3 ClientHello, this vector MUST contain exactly one byte set to zero, which corresponds to the "null" TLS Compression method in prior versions of TLS. If a TLS 1.3 ClientHello is received with any other value in this field, the server MUST abort the TLS Handshake with an "illegal_parameter" TLS Alert Message. Note that TLS 1.3 servers might receive TLS 1.2 or prior ClientHellos which contain other compression methods and MUST follow the procedures for the appropriate prior version of TLS. TLS 1.3 ClientHellos are identified as having a legacy_version of 0x0303 and a supported_versions extension present with 0x0304 as the highest version indicated therein.

extensions - Clients request extended functionality from servers by sending data in the extensions field. The actual "extensions" format is defined in TLS 1.3 Section 4.2. In TLS 1.3, use of certain extensions is mandatory, as functionality is moved into extensions to preserve ClientHello compatibility with previous versions of TLS. Servers MUST ignore unrecognized TLS extensions.

All versions of TLS allow extensions to optionally follow the compression_methods field as an extensions field. TLS 1.3 ClientHello messages always contain extensions (minimally, "supported_versions", or they will be interpreted as TLS 1.2 ClientHello messages), however TLS 1.3 servers might receive ClientHello messages without an extensions field from prior versions of TLS. The presence of extensions can be detected by determining whether there are bytes following the compression_methods field at the end of the ClientHello. Note that this method of detecting optional data differs from the normal TLS method of having a variable-length field, but it is used for compatibility with TLS before extensions were defined. TLS 1.3 servers will need to perform this check first and only attempt to negotiate TLS 1.3 if a "supported_version" extension is present. If negotiating a version of TLS prior to TLS 1.3, a server MUST check that the message either contains no data after legacy_compression_methods or that it contains a valid extensions block with no data following. If not, then it MUST abort the TLS Handshake with a "decode_error" alert. In the event that a client requests additional functionality using extensions, and this functionality is not supplied by the server, the client MAY abort the TLS Handshake.

After sending the ClientHello message, the client waits for a ServerHello or HelloRetryRequest message. If early data is in use, the client may transmit early application_data Section 2.3 while waiting for the next handshake message.

More Information#

There might be more information for this subject on one of the following: