Computer Networking Cheatsheet

TLS and Certificates

Use this Computer Networking reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

What TLS provides

Three guarantees, and it is worth keeping them separate because they fail separately.

GuaranteeMechanism
Confidentialitysymmetric AEAD cipher (AES-GCM, ChaCha20-Poly1305)
Integritythe AEAD tag, plus a transcript hash over the handshake
Authenticationthe server's X.509 certificate chained to a trusted root
VersionStatusNotes
SSL 2.0, 3.0broken, removedPOODLE, do not enable
TLS 1.0, 1.1deprecated (RFC 8996)fails PCI and modern browsers
TLS 1.2current, widely requiredstill fine with AEAD suites and PFS
TLS 1.3current, preferred1 RTT handshake, PFS mandatory, RSA key exchange removed

TLS 1.3 removed static RSA key exchange, renegotiation, compression, and CBC suites, which is why most classic TLS attacks simply do not apply to it.

TLS 1.3 handshake

client                                          server
  ClientHello
    supported_versions, key_share (X25519),
    cipher_suites, server_name (SNI), alpn
  ------------------------------------------------>
                                        ServerHello
                              key_share, selected suite
             {EncryptedExtensions, Certificate,
              CertificateVerify, Finished}
  <------------------------------------------------
  {Finished}
  ------------------------------------------------>
  [application data]  <-------->  [application data]

{} encrypted with handshake keys, [] with application keys

One round trip to application data, against two for TLS 1.2. Session resumption with a PSK ticket allows 0-RTT early data, which is replay-prone and so should only carry idempotent requests.

TLS 1.2 for contrast: ClientHello → ServerHello, Certificate, ServerKeyExchange, ServerHelloDone → ClientKeyExchange, ChangeCipherSpec, Finished → ChangeCipherSpec, Finished, two round trips before data.

Certificate fields that matter

FieldHoldsGotcha
Subject CNlegacy nameignored by modern clients, SAN is authoritative
Subject Alternative Namethe DNS names and IPs the cert is valid formust list every hostname served
Issuerthe signing CAmust chain to a trusted root
Not Before / Not Aftervalidity windowclock skew causes false failures
Public KeyRSA 2048+ or ECDSA P-256ECDSA is smaller and faster
Signature AlgorithmSHA-256 or betterSHA-1 certs are rejected
Basic ConstraintsCA:TRUE/FALSEa leaf must be FALSE
Key Usage / EKUdigitalSignature, serverAuthwrong EKU fails validation
AIAissuer cert and OCSP URLshow clients fetch a missing intermediate
CRL Distribution Pointsrevocation list URL—
SCTCertificate Transparency proofsChrome requires them

Wildcards match one label only: *.example.com covers www.example.com but not example.com itself nor a.b.example.com.

Chain of trust and validation

Root CA (self-signed, in the OS or browser trust store)
   └── Intermediate CA (signs leaves, ships with the server)
          └── Leaf / end-entity certificate (your hostname)

The server must send the leaf plus every intermediate, in order, but not the root. A missing intermediate is the single most common TLS misconfiguration: browsers often paper over it by fetching via AIA, while curl, Java, and Go clients fail outright. That is the shape of "works in my browser, fails in CI".

Validation checks, all of which must pass: signature chain to a trusted root, current date inside the validity window, hostname matches a SAN entry, EKU includes serverAuth, and the cert is not revoked (OCSP, CRL, or an OCSP stapled response from the server).

Failure stringReal cause
unable to get local issuer certificatemissing intermediate, or an untrusted private root
certificate has expiredexpired cert, or a wrong system clock
Hostname mismatchthe name is not in the SAN list
self signed certificate in certificate chainprivate CA not installed in the trust store
SSL routines::wrong version numberplain HTTP spoken to a TLS port, or the reverse
no shared cipherversion or suite mismatch, often TLS 1.0 client to a 1.2+ server

Inspect and debug with openssl

# full handshake, chain, negotiated version and suite
openssl s_client -connect example.com:443 -servername example.com
openssl s_client -connect example.com:443 -showcerts </dev/null
openssl s_client -connect example.com:443 -tls1_2   # force a version
openssl s_client -connect example.com:443 -alpn h2 </dev/null | grep ALPN

# read a certificate
openssl x509 -in cert.pem -noout -text
openssl x509 -in cert.pem -noout -subject -issuer -dates
openssl x509 -in cert.pem -noout -ext subjectAltName
openssl x509 -in cert.pem -noout -fingerprint -sha256

# expiry check straight off a live host
echo | openssl s_client -connect example.com:443 -servername example.com \
  2>/dev/null | openssl x509 -noout -enddate

# verify a chain locally
openssl verify -CAfile chain.pem cert.pem

# does the key match the cert? the two moduli must be identical
openssl x509 -noout -modulus -in cert.pem | openssl sha256
openssl rsa  -noout -modulus -in key.pem  | openssl sha256

# CSR and self-signed cert for local development
openssl req -new -newkey rsa:2048 -nodes -keyout key.pem -out req.csr \
  -subj "/CN=example.com"
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem \
  -days 365 -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
curl -vI https://example.com                # verbose handshake summary
curl --resolve example.com:443:203.0.113.9 https://example.com  # test an origin
nmap --script ssl-enum-ciphers -p 443 example.com
FormatEncodingTypical extensions
PEMbase64 with -----BEGIN----- headers.pem .crt .cer .key
DERbinary.der .cer
PKCS#12encrypted bundle, cert plus key.p12 .pfx
PKCS#8private key container.key
openssl x509 -in cert.der -inform der -out cert.pem -outform pem
openssl pkcs12 -in bundle.pfx -out all.pem -nodes

SNI, ALPN, and modern extensions

- SNI puts the hostname in the ClientHello so one IP can serve many certificates. It is sent in cleartext in TLS 1.2 and 1.3, which ECH (Encrypted Client Hello) is designed to fix. Omitting -servername in s_client is a classic self-inflicted "wrong certificate" result. - ALPN negotiates the application protocol inside the handshake, which is how h2 is selected without an extra round trip. HTTP/2 over TLS requires it. - Perfect forward secrecy comes from ephemeral key exchange (ECDHE, X25519), so capturing traffic today and stealing the private key later does not decrypt it. Mandatory in TLS 1.3, and it is why static RSA suites were removed. - mTLS adds a client certificate: the server sends a CertificateRequest and validates the client chain the same way. Common for service-to-service auth. - HSTS (Strict-Transport-Security) tells browsers to refuse plaintext for a domain, which closes the redirect-stripping window. It is an HTTP header, not a TLS feature, but it is part of the same posture. - Certificate lifetimes keep shrinking. Public certs are capped at well under a year now, so automated renewal (ACME, certbot, lego, caddy) is the only sane operating model, plus monitoring on expiry.