SyntaxStudy
Sign Up
Web Security How TLS Works: Handshake and Certificate Chains
Web Security Beginner 2 min read

How TLS Works: Handshake and Certificate Chains

Transport Layer Security (TLS) is the cryptographic protocol that secures HTTPS connections. When a browser connects to an HTTPS server, the two parties perform a TLS handshake before any application data flows. In TLS 1.3 — the current standard — the handshake takes just one round trip: the client sends its supported cipher suites and a key share; the server responds with its chosen cipher, its own key share, and its certificate chain. Both sides independently derive the same symmetric session keys using the Diffie-Hellman exchange, and encrypted communication begins. A TLS certificate is an X.509 document signed by a Certificate Authority (CA). Browsers ship with a list of trusted root CAs. Servers typically present a chain: the server's leaf certificate signed by an intermediate CA, which is signed by a root CA. The browser walks the chain, verifying each signature, until it reaches a trusted root. This chain of trust prevents imposters from presenting self-signed certificates and being accepted by browsers. Certificate Transparency (CT) logs require CAs to publish every issued certificate in public append-only logs. Browsers check that a certificate appears in at least two CT logs (via Signed Certificate Timestamps embedded in the TLS handshake). CT makes it impossible for a rogue CA to issue a certificate for your domain without that certificate being visible to domain owners and security researchers.
Example
# Inspect a live TLS certificate chain with openssl

# Full handshake dump — shows TLS version, cipher, and certificate chain
openssl s_client -connect example.com:443 -showcerts

# Extract just the leaf certificate and print human-readable details
openssl s_client -connect example.com:443 </dev/null 2>/dev/null \
  | openssl x509 -noout -text \
  | grep -E 'Subject:|Issuer:|Not Before|Not After|DNS:'

# Check which TLS versions the server accepts
for version in tls1_2 tls1_3; do
  result=$(openssl s_client -connect example.com:443 -$version </dev/null 2>&1)
  if echo "$result" | grep -q "CONNECTED"; then
    echo "$version: SUPPORTED"
  else
    echo "$version: NOT supported"
  fi
done

# Verify a certificate file against a CA bundle
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt server.crt

# Check certificate expiry (exit 1 if expiring within 30 days)
openssl x509 -checkend $((30*86400)) -noout -in server.crt \
  && echo "Certificate is valid for at least 30 more days" \
  || echo "WARNING: certificate expires within 30 days"