Last Updated: July 15, 2025
TLS Handshake (v1.3)
1. ClientHelloClient sends supported ciphers, key share (ECDHE), SNI hostname
2. ServerHelloServer picks cipher, sends key share + certificate chain
3. Server FinishedServer sends encrypted Finished message — handshake done in 1-RTT
4. Client FinishedClient verifies cert, sends encrypted Finished — secure channel open
Certificate Chain
Root CASelf-signed, pre-installed in OS/browser trust stores (e.g., ISRG Root X1)
Intermediate CASigned by Root — bridges trust to leaf certs (e.g., R3 for Let's Encrypt)
Leaf CertificateYour domain's cert — contains CN/SANs, public key, validity period
openssl Diagnostics
openssl s_client -connect example.com:443 -servername example.comFull handshake dump — cert chain, cipher, TLS version
openssl x509 -in cert.pem -text -nooutInspect certificate details — SANs, expiry, issuer
openssl s_client -connect host:443 -tls1_2Force specific TLS version to test compatibility
openssl verify -CAfile chain.pem cert.pemVerify certificate against CA chain
openssl req -new -newkey rsa:2048 -nodes -keyout key.pem -out csr.pemGenerate private key + CSR for a new certificate
Cipher Suites (TLS 1.3)
| Suite | Key Exchange | Encryption | Hash |
|---|---|---|---|
TLS_AES_128_GCM_SHA256 | ECDHE | AES-128-GCM | SHA-256 |
TLS_AES_256_GCM_SHA384 | ECDHE | AES-256-GCM | SHA-384 |
TLS_CHACHA20_POLY1305_SHA256 | ECDHE | ChaCha20 | SHA-256 |
mTLS (Mutual TLS)
| Item | Description |
|---|---|
What it is | Client also presents certificate — server authenticates client |
Use cases | Service mesh (Istio/Linkerd), zero-trust, machine-to-machine APIs |
Config | Server sets ssl_client_certificate + ssl_verify_client on (nginx) |
Pro Tip: Always pin the minimum TLS version your app requires (1.2+ minimum, 1.3 preferred). Older versions leave you vulnerable to downgrade attacks.