Documentation

# TLS/SSL Basics: Understanding Secure Web Communication

HTTPS FOUNDATION NETWORK ENCRYPTION ESSENTIAL KNOWLEDGE

# What is TLS/SSL?

CORE DEFINITION

Simple Definition: TLS (Transport Layer Security) and its predecessor SSL (Secure Sockets Layer) are cryptographic protocols that provide secure communication over computer networks. When you see the padlock icon and "HTTPS" in your browser, that's TLS in action.

What TLS Does:

  • Encrypts data so eavesdroppers can't read it
  • Verifies server identity to prevent impersonation
  • Detects tampering to ensure data integrity
  • Establishes secure keys for the session

SSL IS DEPRECATED DON'T USE SSL


# Why TLS/SSL Matters

CRITICAL SECURITY

# Without TLS/SSL (HTTP) INSECURE

Three Critical Vulnerabilities:

Eavesdropping - Anyone on the network can read your data in plain text Tampering - Attackers can modify data in transit without detection Impersonation - No way to verify you're actually talking to the real server

GET /login HTTP/1.1
Host: bank.com
Content-Type: application/x-www-form-urlencoded

username=john&password=secret123

# With TLS/SSL (HTTPS) SECURE

Three Security Guarantees:

Confidentiality - Data is encrypted with AES-256 or similar Integrity - Detects any tampering with HMAC or AEAD Authentication - Verifies server identity with certificates

hex
16 03 03 00 a5 01 00 00 a1 03 03 5f 4e 8c 3a b2 8d 6f 3c 4a 9e 2f 1b 7d ...
c3 5a 8f 2e 9b 4d 7c 1a 6e 3f 8c 2d 9f 5b 4e 7a 1c 6d 3e 8f 2c 9b ...

# TLS/SSL Version History

PROTOCOL EVOLUTION

# Evolution of Security Protocols

Protocol Year Status Security Notes
SSL 1.0 1994 Never released NEVER USED Fatally flawed So broken it was never publicly released
SSL 2.0 1995 INSECURE BROKEN Completely broken DROWN attack (2016), protocol flaws
SSL 3.0 1996 INSECURE BROKEN Completely broken POODLE attack (2014), padding oracle
TLS 1.0 1999 DEPRECATED BANNED Weak, vulnerable PCI-DSS banned since 2018, BEAST attack
TLS 1.1 2006 DEPRECATED BANNED Weak, limited use PCI-DSS banned since 2018, rarely used
TLS 1.2 2008 CURRENT SECURE Secure (when properly configured) Current standard, widely deployed
TLS 1.3 2018 RECOMMENDED BEST Most secure, faster Simplified handshake, removed legacy crypto

# How TLS/SSL Works

CORE MECHANISMS

# The Three Goals of TLS

Goal: Keep data secret from eavesdroppers

How: Symmetric encryption algorithms (AES-256-GCM, ChaCha20-Poly1305)

plaintext
Plaintext:  "Hello, World!"
                  ↓
         [Encryption with AES-256-GCM]
                  ↓
Ciphertext: "8f3a9c7e2d1b5a4f9e3c7d2a..."

Key Point: Only sender and receiver can read the data. Even if an attacker records all traffic, they cannot decrypt it without the session keys.

Real-World Impact:

  • Credit card numbers encrypted during purchase
  • Passwords hidden when logging in
  • Private messages unreadable by ISP
  • File uploads/downloads protected

Goal: Detect if data was tampered with during transmission

How: Message Authentication Codes (HMAC) or Authenticated Encryption (AEAD like GCM)

plaintext
Message: "Transfer $100 to Bob"
    ↓
MAC: HMAC-SHA256(message, secret_key)
    = "a5f9c3e7b2..."

If attacker changes to "Transfer $1000 to Eve":
→ MAC won't match: "a5f9c3e7b2..." ≠ "x7k2m9n4p1..."
→ Tampering detected!
→ Connection terminated immediately

Key Point: Any modification - even a single bit - will be instantly detected and the connection terminated.

Attacks Prevented:

  • Changing transaction amounts
  • Injecting malicious code
  • Bit-flipping attacks
  • Replay attacks (reusing old messages)

Goal: Verify you're talking to the real server, not an imposter

How: Digital certificates signed by trusted Certificate Authorities (CAs)

plaintext
🌐 Browser: "Prove you're really bank.com"
    ↓
🏦 Server:  "Here's my certificate signed by DigiCert"
    ↓
🔍 Browser: Checks certificate:
    - Is it signed by a trusted CA? ✅ (DigiCert)
    - Is it for bank.com domain? ✅
    - Is it still valid (not expired)? ✅
    - Has it been revoked? ✅ (Check CRL/OCSP)
    ↓
✅ Browser: "I trust DigiCert, so I trust you're really bank.com"
    ↓
🔒 Secure connection established

Key Point: Prevents impersonation and man-in-the-middle attacks. You know you're talking to the real server.

Certificate Chain of Trust:

  1. Root CA (DigiCert, Let's Encrypt) - Trusted by browser
  2. Intermediate CA - Signs server certificates
  3. Server Certificate - Proves server identity

# The TLS Handshake

The TLS handshake is the process of establishing a secure connection. Think of it as a secret handshake before sharing secrets.

# TLS 1.2 Handshake (Legacy)

Client                                           Server

1. ClientHello
   - Supported versions: TLS 1.2
   - Cipher suites: [list]
   - Random: 28 bytes
                        ────────────────>

                                         2. ServerHello
                                            - Selected cipher suite
                                            - Random: 28 bytes
                                         3. Certificate
                                            - Server's certificate chain
                                         4. ServerKeyExchange
                                            - Key exchange parameters
                                         5. ServerHelloDone
                        <────────────────

6. ClientKeyExchange
   - Client's key exchange data
7. ChangeCipherSpec
8. Finished
   - Encrypted handshake verification
                        ────────────────>

                                         9. ChangeCipherSpec
                                         10. Finished
                                            - Encrypted handshake verification
                        <────────────────

        [Application Data - Encrypted Communication]
                        <══════════════>

Time: 2 round-trips (2-RTT) before data transfer

# TLS 1.3 Handshake (Modern)

Client                                           Server

1. ClientHello
   - Supported versions: TLS 1.3
   - Cipher suites: [list]
   - Extensions: SNI, ALPN
   - Key share (ECDHE public key)
                        ────────────────>

                                         2. ServerHello
                                            - Selected cipher suite
                                            - Key share (ECDHE public key)
                                         {EncryptedExtensions}
                                         {Certificate}
                                         {CertificateVerify}
                                         {Finished}
                        <────────────────

{Finished}
                        ────────────────>

        [Application Data - Encrypted Communication]
                        <══════════════>

Time: 1 round-trip (1-RTT) before data transfer

TLS 1.3 Improvements:

  • 50% faster - Only 1 round-trip
  • Encrypted earlier - More of handshake is encrypted
  • Simpler - Removed weak algorithms
  • Always forward secrecy - Ephemeral keys required

For resuming previous connections:

Client                                    Server

ClientHello
   + EarlyData (Application Data!)
                  ──────────────────>

                                    ServerHello
                                    {EncryptedExtensions}
                                    {Finished}
                  <──────────────────

{Finished}
                  ──────────────────>

        [More Application Data]

Benefits:

  • Zero latency - Instant data transmission
  • Perfect for APIs and mobile apps

Risks:

  • Replay attacks - 0-RTT data can be replayed
  • Not idempotent - Only use for safe operations (GET, not POST)

Recommendation: Disable 0-RTT unless you understand the risks.


# Detailed Handshake Messages

# ClientHello

The client starts the handshake by sending supported options:

{
  "version": "TLS 1.3",
  "random": "28 bytes of random data",
  "session_id": "for session resumption",
  "cipher_suites": [
    "TLS_AES_256_GCM_SHA384",
    "TLS_CHACHA20_POLY1305_SHA256",
    "TLS_AES_128_GCM_SHA256"
  ],
  "compression_methods": [0],  // No compression (CRIME attack)
  "extensions": {
    "server_name": "example.com",  // SNI
    "supported_groups": ["x25519", "secp256r1"],
    "signature_algorithms": ["rsa_pss_rsae_sha256", "ecdsa_secp256r1_sha256"],
    "key_share": {
      "group": "x25519",
      "public_key": "client's ephemeral public key"
    }
  }
}

# ServerHello

The server responds with selected options:

{
  "version": "TLS 1.3",
  "random": "28 bytes of random data",
  "session_id": "echo from ClientHello",
  "cipher_suite": "TLS_AES_256_GCM_SHA384",
  "compression_method": 0,
  "extensions": {
    "key_share": {
      "group": "x25519",
      "public_key": "server's ephemeral public key"
    }
  }
}

# Certificate

Server sends its certificate chain:

{
  "certificates": [
    {
      "certificate": "--- Leaf Certificate (example.com) ---",
      "extensions": {
        "status_request": "OCSP staple (optional)"
      }
    },
    {
      "certificate": "--- Intermediate Certificate ---"
    }
    // Root certificate not included (already trusted)
  ]
}

# CertificateVerify

Server proves it owns the private key:

{
  "algorithm": "rsa_pss_rsae_sha256",
  "signature": "Digital signature over handshake transcript"
}

Verification:

1. Client has server's public key (from certificate)
2. Client verifies signature using public key
3. Signature valid → Server owns private key ✓

# Finished

Both parties send Finished message:

{
  "verify_data": "HMAC over entire handshake transcript"
}

Purpose: Ensures handshake wasn't tampered with.


# Key Generation

After the handshake, both parties derive symmetric encryption keys:

# Key Derivation Process

                   Pre-Shared Key (PSK) or 0
                            |
                            v
                    Extract (HKDF-Extract)
                            |
                            v
                      Early Secret
                            |
                            +-----> Derive Early Traffic Keys (0-RTT)
                            |
                    (Derive more secrets)
                            |
                            v
                    Handshake Secret
                            |
                            +-----> Client Handshake Traffic Secret
                            +-----> Server Handshake Traffic Secret
                            |
                    (Derive more secrets)
                            |
                            v
                      Master Secret
                            |
                            +-----> Client Application Traffic Secret
                            +-----> Server Application Traffic Secret
                            +-----> Resumption Master Secret
# After ECDHE key exchange
shared_secret = ecdhe_compute_shared(client_private, server_public)

# Extract
early_secret = HKDF_Extract(salt=0, ikm=PSK or 0)

# Derive handshake secret
handshake_secret = HKDF_Extract(
    salt=derive_secret(early_secret, "derived"),
    ikm=shared_secret
)

# Derive traffic keys
client_handshake_key = HKDF_Expand_Label(
    handshake_secret,
    "c hs traffic",
    ClientHello...ServerHello,
    key_length
)

server_handshake_key = HKDF_Expand_Label(
    handshake_secret,
    "s hs traffic",
    ClientHello...ServerHello,
    key_length
)

# Derive application traffic keys
master_secret = HKDF_Extract(
    salt=derive_secret(handshake_secret, "derived"),
    ikm=0
)

client_app_key = HKDF_Expand_Label(
    master_secret,
    "c ap traffic",
    ClientHello...ServerFinished,
    key_length
)

server_app_key = HKDF_Expand_Label(
    master_secret,
    "s ap traffic",
    ClientHello...ServerFinished,
    key_length
)

# Multiple Keys for Different Purposes

Why multiple keys?

Key Purpose Direction
Client Write Key Encrypt client → server Client encrypts
Server Write Key Encrypt server → client Server encrypts
Client Write IV Initialization vector Prevents patterns
Server Write IV Initialization vector Prevents patterns

Benefits:

  • Separation - Compromise of one key doesn't affect others
  • Independence - Each direction uses different keys
  • Nonce uniqueness - IVs ensure no key reuse

# Session Resumption

Problem: Full handshake is expensive (CPU + latency)

Solution: Resume previous sessions without full handshake

# Session IDs (TLS 1.2)

First Connection:

Client → Server: ClientHello (session_id = empty)
Server → Client: ServerHello (session_id = 1234)
                 [Full handshake]
Server stores session 1234 with master secret

Resumed Connection:

Client → Server: ClientHello (session_id = 1234)
Server finds session 1234 in cache
Server → Client: ServerHello (session_id = 1234)
                 ChangeCipherSpec
                 Finished
[Skip certificate exchange, use cached master secret]

Benefit: Saves 1 round-trip and CPU (no public key crypto)

# Session Tickets (TLS 1.2 & 1.3)

First Connection:

Client → Server: ClientHello
Server → Client: ServerHello
                 [Full handshake]
                 NewSessionTicket
                 (Encrypted session state)
Client stores encrypted ticket

Resumed Connection:

Client → Server: ClientHello
                 + Encrypted ticket
Server decrypts ticket, retrieves session state
Server → Client: ServerHello
                 [Abbreviated handshake]

Benefits:

  • Stateless - Server doesn't store sessions
  • Scalable - No session cache coordination
  • Encrypted - Ticket is encrypted with server's key

Security Note: Rotate ticket encryption keys regularly!

# PSK (Pre-Shared Key) Resumption - TLS 1.3

Client → Server: ClientHello
                 + PSK identity
                 + PSK binder (proves PSK knowledge)
Server → Client: ServerHello
                 + Selected PSK
[Skip certificate, use PSK as master secret]

Even faster than session tickets!


# Basic TLS Implementation

# Client Example

[Python - TLS Client]
import ssl
import socket

# Create SSL context
context = ssl.create_default_context()

# Optional: Verify certificate
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED

# Connect to server
with socket.create_connection(('example.com', 443)) as sock:
    with context.wrap_socket(sock, server_hostname='example.com') as ssock:
        # Print connection info
        print(f"TLS Version: {ssock.version()}")
        print(f"Cipher: {ssock.cipher()}")

        # Get certificate
        cert = ssock.getpeercert()
        print(f"Server: {cert['subject']}")

        # Send HTTP request
        ssock.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")

        # Receive response
        response = ssock.recv(4096)
        print(response.decode())
[Node.js - TLS Client]
const tls = require('tls');
const fs = require('fs');

const options = {
  host: 'example.com',
  port: 443,

  // Verify certificate
  rejectUnauthorized: true,

  // Optional: Custom CA
  ca: fs.readFileSync('ca-cert.pem'),
};

const socket = tls.connect(options, () => {
  console.log('Connected');
  console.log('TLS Version:', socket.getProtocol());
  console.log('Cipher:', socket.getCipher());

  // Verify certificate
  if (!socket.authorized) {
    console.error('Certificate not authorized:', socket.authorizationError);
  }

  // Send data
  socket.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
});

socket.on('data', (data) => {
  console.log(data.toString());
});

socket.on('end', () => {
  console.log('Disconnected');
});
[Java - TLS Client]
import javax.net.ssl.*;
import java.io.*;

public class TLSClient {
    public static void main(String[] args) throws Exception {
        // Create SSL context
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, null, null);

        // Create socket factory
        SSLSocketFactory factory = sslContext.getSocketFactory();

        // Connect to server
        try (SSLSocket socket = (SSLSocket) factory.createSocket("example.com", 443)) {
            // Print connection info
            SSLSession session = socket.getSession();
            System.out.println("Protocol: " + session.getProtocol());
            System.out.println("Cipher: " + session.getCipherSuite());

            // Send HTTP request
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            out.println("GET / HTTP/1.1");
            out.println("Host: example.com");
            out.println();
            out.flush();

            // Read response
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream())
            );

            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        }
    }
}

# Server Example

[Python - TLS Server]
import ssl
import socket

# Create SSL context
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)

# Load certificate and private key
context.load_cert_chain('cert.pem', 'key.pem')

# Optional: Set TLS version
context.minimum_version = ssl.TLSVersion.TLSv1_2
context.maximum_version = ssl.TLSVersion.TLSv1_3

# Optional: Set cipher suites
context.set_ciphers('ECDHE+AESGCM:ECDHE+CHACHA20')

# Create socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.bind(('0.0.0.0', 443))
    sock.listen(5)

    print("TLS Server listening on port 443...")

    while True:
        conn, addr = sock.accept()
        with context.wrap_socket(conn, server_side=True) as ssock:
            print(f"Connection from {addr}")
            print(f"TLS Version: {ssock.version()}")
            print(f"Cipher: {ssock.cipher()}")

            # Receive data
            data = ssock.recv(1024)
            print(f"Received: {data.decode()}")

            # Send response
            response = b"HTTP/1.1 200 OK\r\n\r\nHello from TLS server!"
            ssock.sendall(response)
[Node.js - TLS Server]
const tls = require('tls');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem'),

  // Optional: Certificate chain
  ca: fs.readFileSync('chain.pem'),

  // TLS versions
  minVersion: 'TLSv1.2',
  maxVersion: 'TLSv1.3',

  // Cipher suites
  ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384',

  // Client certificate (optional)
  requestCert: false,
  rejectUnauthorized: false
};

const server = tls.createServer(options, (socket) => {
  console.log('Client connected');
  console.log('TLS Version:', socket.getProtocol());
  console.log('Cipher:', socket.getCipher());

  socket.on('data', (data) => {
    console.log('Received:', data.toString());
    socket.write('HTTP/1.1 200 OK\r\n\r\nHello from TLS server!');
  });

  socket.on('end', () => {
    console.log('Client disconnected');
  });
});

server.listen(443, () => {
  console.log('TLS Server listening on port 443');
});

# Quick Reference

# TLS Versions

NEVER USE

  • SSL 2.0, SSL 3.0
  • TLS 1.0, TLS 1.1

USE THESE

  • TLS 1.2 (with strong ciphers)
  • TLS 1.3 (recommended)

# Handshake Speed

Version Round-Trips Speed
TLS 1.2 2-RTT Baseline
TLS 1.3 1-RTT 50% faster
TLS 1.3 0-RTT 0-RTT Instant (with risks)

# Key Algorithms

Recommended:

  • ECDHE (Ephemeral Diffie-Hellman with Elliptic Curves)
  • AES-GCM (256-bit or 128-bit)
  • ChaCha20-Poly1305

Avoid:

  • RSA key exchange
  • RC4, 3DES
  • MD5, SHA1

# Next Steps

# Related Topics

HSTS - HTTP Strict Transport Security Certificate Chain of Trust - Understanding PKI SNI (Server Name Indication) - Multiple HTTPS sites on one IP Certificate Revocation - CRL and OCSP Forward Secrecy - Perfect Forward Secrecy Cipher Suites - Understanding encryption recipes

# Learning Resources

Books:

  • "Bulletproof SSL and TLS" by Ivan Ristić
  • "Network Security with OpenSSL" by Viega, Messier & Chandra

Tools:


# Protected by Layerd AI

Layerd AI Guardian Proxy provides comprehensive TLS/SSL security:

TLS Enforcement - Blocks non-HTTPS connections Version Control - Blocks outdated protocols (TLS 1.0, 1.1) Certificate Validation - Verifies certificate chains Real-time Monitoring - Alerts on certificate expiry

Learn more about Layerd AI Protection →


Last updated: November 2025