Skip to content

TLS Internals | Networking - Wyatt's Notes

flowchart TD
A[Tls Internals] --> B[Key Concepts]
A --> C[Core Principles]
A --> D[Practical Applications]
B --> E[Fundamental definitions]
C --> F[Design patterns]
D --> G[Real-world usage]

This document goes deeper into TLS internals than the TLS fundamentals document, covering the record Layer architecture, detailed handshake message formats for TLS 1.3, cipher suite construction, key Exchange mechanisms, and common implementation pitfalls. This is the material you need to understand When debugging TLS connections, configuring servers, or evaluating cryptographic strength.

TLS is structured as a layered protocol with four sub-protocols operating over a reliable transport (TCP):

+-----------------------------------+
| Application Data |
+-----------------------------------+
| Handshake Protocol |
+-----------------------------------+
| Change Cipher Spec |
+-----------------------------------+
| Alert Protocol |
+-----------------------------------+
| Record Layer |
+-----------------------------------+
| TCP |
+-----------------------------------+

The TLS record layer fragments application data (and handshake messages) into records. Each record Has:

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Content Type (8) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Version (16) |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Length (16) |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fragment (variable) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Content types:

TypeValueDescription
CHANGE_CIPHER_SPEC20Deprecated in TLS 1.3 (replaced by KeyUpdate)
ALERT21Error or warning notifications
HANDSHAKE22Handshake protocol messages
APPLICATION_DATA23Encrypted application data

The handshake protocol is responsible for authentication, key exchange, and negotiation of Cryptographic parameters. Handshake messages are carried inside TLS records with content type 22.

Alert messages convey errors and state changes:

LevelDescriptionCommon Alerts
Warning (1)Non-fatal; connection continuesclose_notify, no_certificate, bad_certificate
Fatal (2)Connection must be terminatedhandshake_failure, decode_error, illegal_parameter

In TLS 1.2, this protocol signals the transition to encrypted communication. In TLS 1.3, it is Deprecated. Key changes are signaled within the handshake protocol itself.

FeatureTLS 1.2TLS 1.3Reason
RenegotiationSupportedRemovedComplex, caused RC4 injection attacks
CompressionSupportedRemovedCRIME attack (compression oracle)
Static RSA key exchangeSupportedRemovedNo forward secrecy
Non-AEAD ciphersSupportedRemovedCBC ciphers vulnerable to padding oracles
Custom DHE groupsSupportedRemovedWeak groups (e.g., export-grade)
SHA-1 in signaturesSupportedRemovedSHA-1 is cryptographically weak
MD5 in signaturesSupportedRemovedMD5 is broken
FeatureDescription
0-RTT dataSend application data in the first flight (repeat connections)
Signature algorithmsExplicit negotiation of hash+signature pairs (RFC 8446 Section 4.2.3)
Key scheduleDerived key hierarchy using HKDF (RFC 5869)
Post-handshake authServer can request client certificate after the handshake
Encrypted Server HelloServer Hello is encrypted (hides server identity from observers)
KeyUpdateIn-band key rotation without renegotiation

TLS 1.2 cipher suites are complex strings like TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. TLS 1.3 Cipher suites only specify the AEAD algorithm:

TLS 1.3 Cipher SuiteAEAD AlgorithmHash (HKDF)
TLS_AES_128_GCM_SHA256AES-128-GCMSHA-256
TLS_AES_256_GCM_SHA384AES-256-GCMSHA-384
TLS_CHACHA20_POLY1305_SHA256ChaCha20-Poly1305SHA-256
TLS_AES_128_CCM_SHA256AES-128-CCMSHA-256
TLS_AES_128_CCM_8_SHA256AES-128-CCM-8SHA-256

The key exchange algorithm is no longer part of the cipher suite. It is negotiated separately via The supported_groups extension.

Client Server
| |
|--- ClientHello -------------------------------->| Flight 1
| supported_versions, supported_groups, |
| signature_algorithms, key_share |
| |
|<-- ServerHello ---------------------------------| Flight 2
| selected_version, selected_group, |
| key_share |
|<-- EncryptedExtensions ------------------------|
|<-- Certificate ---------------------------------|
|<-- CertificateVerify ---------------------------|
|<-- Finished ------------------------------------|
| |
|--- Finished ----------------------------------->| Flight 3
| |
|==== Application Data =========================|

The ClientHello carries the client”s capabilities and parameters:

FieldDescription
legacy_version0x0303 (TLS 1.2) for compatibility with middleboxes
random32 bytes of random (used in key derivation)
legacy_session_idSession ID for compatibility (TLS 1.3 uses PSK)
cipher_suitesList of supported TLS 1.3 cipher suites
legacy_compression_methods[0x00] (no compression)
extensionssupported_versions, supported_groups, key_share,
signature_algorithms, psk_key_exchange_modes,
server_name (SNI), etc.
FieldDescription
legacy_version0x0303 (always, even for TLS 1.3)
random32 bytes of random
legacy_session_id_echoEcho of client’s session_id
cipher_suiteSelected cipher suite
legacy_compression_method0x00
extensionssupported_version (TLS 1.3), key_share,
pre_shared_key (if PSK selected)

After the ServerHello, all subsequent handshake messages are encrypted. EncryptedExtensions carries Server-side configuration that does not affect the cryptographic parameters:

  • server_name indication (whether SNI was used)
  • max_fragment_length (negotiate smaller records)
  • application_layer_protocol_negotiation (ALPN)
  • early_data (whether 0-RTT is accepted)

The server sends its certificate chain. In TLS 1.3, the Certificate message is sent encrypted. The Certificate chain includes:

  1. Leaf certificate: The server’s end-entity certificate
  2. Intermediate certificates: One or more intermediate CA certificates
  3. Root certificate: NOT included (the client must already trust it)

This message proves that the server holds the private key corresponding to the certificate’s public Key. It contains a digital signature over a transcript hash of all handshake messages so far.

Signature = Sign(private_key, Hash("TLS 1.3, server CertificateVerify" || 0x20...0x20 || transcript_hash))

The 0x20...0x20 is 64 bytes of spaces (0x20), a context string that binds the signature to TLS 1.3 Specifically.

Both sides send a Finished message, which contains a verify_data value derived from the handshake Transcript:

verify_data = HMAC(finished_key, Hash(transcript))

The Finished message is the first message encrypted with the newly derived traffic keys. If the Verify_data does not match, the handshake has been tampered with and the connection is terminated.

ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)

Section titled “ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)”

The most widely used key exchange in TLS 1.3. Both sides generate an ephemeral (temporary) key pair On an elliptic curve, exchange public keys, and derive a shared secret.

Client generates: (priv_c, pub_c)
Server generates: (priv_s, pub_s)
Shared secret = ECDH(priv_c, pub_s) = ECDH(priv_s, pub_c) = x-coordinate of (priv_c * pub_s)

Supported curves (RFC 8446):

CurveKey SizeSecurity Level
X25519256 bits128 bits
secp256r1 (P-256)256 bits128 bits
secp384r1 (P-384)384 bits192 bits
secp521r1 (P-521)521 bits256 bits

X25519 is the recommended default. It is faster than NIST curves, has simpler implementation (fewer Edge cases), and uses a constant-time algorithm that is resistant to timing attacks.

DHE (Finite Field Diffie-Hellman Ephemeral)

Section titled “DHE (Finite Field Diffie-Hellman Ephemeral)”

Traditional Diffie-Hellman over a finite field. Slower than ECDHE for equivalent security levels. Supported groups:

Group (ffdhe)Prime SizeSecurity Level
ffdhe20482048 bits112 bits
ffdhe30723072 bits128 bits
ffdhe40964096 bits150 bits
ffdhe61446144 bits175 bits
ffdhe81928192 bits200+ bits

TLS 1.3 supports PSK-based key exchange, which can be used alone or combined with (EC)DHE (called “PSK with (EC)DHE” or “psk_dhe_ke”).

PSK ModeForward SecrecyUse Case
PSK onlyNoIoT devices, resumption tickets
PSK + (EC)DHEYesRecommended for resumption (security)

PSKs are established either externally (configured on both sides) or via a previous TLS handshake (session resumption via NewSessionTicket).

The client indicates which PSK modes it supports in the psk_key_exchange_modes extension:

  • psk_ke: PSK-only key establishment (no forward secrecy)
  • psk_dhe_ke: PSK combined with (EC)DHE (forward secrecy maintained)

TLS is like a secure diplomatic pouch system. The handshake is like two ambassadors meeting, verifying each other’s credentials (certificates), and agreeing on a secret code (shared secret) for their correspondence. The record layer is like the pouch itself - it wraps messages so eavesdroppers cannot read them and tamperers cannot modify them. TLS 1.3 simplified the handshake from two round trips to one, like speeding up the credential verification process. The key insight is that TLS provides confidentiality (encryption), integrity (MAC), and authentication (certificates) - the three pillars of secure communication. Perfect forward secrecy ensures that even if a server’s private key is compromised later, past sessions remain secure.

  • TLS - Overview of TLS protocol versions and deployment best practices
  • HTTP - How HTTPS combines HTTP with TLS for secure web communication
  • Network Tools - Tools for testing TLS certificate configuration and cipher suites