Educational developer tools & learning resources for software development & cybersecurity students — Learn more about our mission

How HTTPS Actually Works: A Developer's Guide to SSL, TLS, and Certificate Pinning

Author Skand K. Apr 08, 2026 9 min read 26 views
How HTTPS Actually Works: A Developer's Guide to SSL, TLS, and Certificate Pinning

Educational Content: This article is written for educational purposes to help developers and cybersecurity students understand software concepts. Always follow ethical guidelines and applicable laws.

Most developers know that HTTPS is important and have it enabled on their sites. Far fewer understand what HTTPS actually does under the hood — which means they also don't understand where it breaks down, what its limitations are, and what certificate pinning addresses. When something goes wrong with SSL configuration (and it will), developers who understand the mechanics can diagnose and fix it in minutes. Those who don't waste hours or make it worse.

This post explains how TLS works at a level of detail that's useful for developers — not a cryptography lecture, but enough to understand certificate validation, common attack vectors, and when certificate pinning makes sense for your application.

What HTTPS Actually Provides

When someone says "HTTPS," they're referring to HTTP running over TLS (Transport Layer Security). TLS is what provides the security. It delivers three things:

Encryption. Data transmitted between the client and server is encrypted in transit. Anyone intercepting the network traffic — an ISP, a coffee shop owner running a packet sniffer, anyone doing a man-in-the-middle attack — sees encrypted bytes, not the actual content of your requests and responses.

Integrity. TLS includes message authentication codes (MACs) that detect any tampering with the data in transit. If someone modifies an encrypted packet, the receiver detects the modification and discards the data.

Authentication. TLS certificates are issued by Certificate Authorities (CAs) that are trusted by browsers and operating systems. When you connect to https://yourbank.com, your browser verifies that the certificate was issued to yourbank.com by a trusted CA, and that the server possesses the corresponding private key. This prevents an attacker from intercepting traffic by presenting a fake site — they'd need a certificate issued to yourbank.com, which they can't get without controlling the domain or compromising a CA.

What HTTPS does not provide: it doesn't guarantee the server is legitimate in any other sense, just that it has a certificate for that domain. Phishing sites can and do obtain legitimate HTTPS certificates for deceptive domains like yourbank-secure-login.com. HTTPS means the connection is encrypted and authenticated to the domain name — not that the destination is trustworthy.

The TLS Handshake: What Actually Happens

Understanding the TLS handshake helps you understand both the security guarantees and the attack surface. Here's what happens when your browser connects to an HTTPS URL (simplified to TLS 1.3, the current standard):

Step 1: Client Hello. Your browser sends a message to the server listing: the TLS version it supports, the cipher suites it supports (combinations of algorithms for key exchange, encryption, and MAC), and a random nonce (bytes used later in key derivation).

Step 2: Server Hello + Certificate. The server responds with: the TLS version selected, the cipher suite selected, its own random nonce, and its digital certificate. The certificate contains the server's public key and is signed by a Certificate Authority.

Step 3: Certificate verification. Your browser verifies the certificate is valid by checking: the domain name in the certificate matches the domain you're connecting to; the certificate hasn't expired; the certificate was signed by a CA in the browser's trust store; the certificate hasn't been revoked (via CRL or OCSP). If any of these checks fail, the browser shows a certificate warning and refuses to proceed by default.

Step 4: Key exchange. In TLS 1.3, the client and server use Elliptic Curve Diffie-Hellman (ECDHE) to establish a shared secret that neither side transmitted over the network. An eavesdropper who captured all the handshake traffic cannot derive this shared secret — that's the "forward secrecy" property of ECDHE.

Step 5: Session keys derived. Both sides derive symmetric encryption keys from the shared secret and the random nonces. From this point, all communication is encrypted with these symmetric keys.

TLS 1.3 (released 2018) is significantly faster than TLS 1.2 — the handshake is one round-trip instead of two for new connections, and zero round-trips for session resumption. If your server still supports TLS 1.0 or 1.1, you should disable them — they have known cryptographic weaknesses and are officially deprecated.

Certificate Types: DV, OV, and EV

Not all SSL certificates provide the same level of vetting:

Domain Validation (DV) certificates verify only that you control the domain name — typically by responding to an email or placing a file in the domain's web root. They're free (Let's Encrypt), issue in seconds, and are what most sites use. They provide encryption but no verification of who operates the site.

Organization Validation (OV) certificates additionally verify that the requesting organization is a registered legal entity. They take days to issue and cost money. The organization name appears in the certificate details, which users can inspect by clicking the lock icon.

Extended Validation (EV) certificates provide the most rigorous vetting — extended verification of the organization's legal existence, identity, and operational details. Previously these displayed the company name in the browser's address bar, but major browsers have removed this UI treatment, making EV less visually distinctive than it used to be.

For most web applications, DV certificates from Let's Encrypt are appropriate and recommended. The encryption strength is identical across certificate types — the difference is entirely in how much identity verification was done.

Common TLS Vulnerabilities and Configuration Mistakes

Even with HTTPS enabled, your configuration may have weaknesses:

Supporting deprecated protocol versions. TLS 1.0 and 1.1 have known vulnerabilities (POODLE, BEAST, others) and should be disabled. TLS 1.2 is acceptable but TLS 1.3 should be preferred. Check your nginx or Apache configuration:

# nginx - recommended TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;

Not enforcing HTTPS with HSTS. If your site is accessible over HTTP and HTTPS, users and search engines may access the HTTP version. An attacker performing a network interception attack (e.g., on a coffee shop network) can intercept the initial HTTP request and prevent the HTTPS upgrade. HTTP Strict Transport Security (HSTS) tells browsers to always use HTTPS for your domain for a specified period, even if the user types http://:

# Add this header to your HTTPS responses (never to HTTP responses)
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

The preload directive lets you submit your domain to browser preload lists, which means browsers will use HTTPS for your domain even on the very first visit (before they've ever seen your HSTS header). You can submit at hstspreload.org.

Mixed content. Loading HTTP resources (scripts, stylesheets, images, API calls) on an HTTPS page creates "mixed content" — the page itself is encrypted but some resources aren't, weakening the overall security model. Browsers block active mixed content (scripts, iframes) and warn on passive mixed content (images). All resources should load over HTTPS.

Certificate not covering all subdomains. A certificate issued to example.com doesn't cover api.example.com or www.example.com unless it's a wildcard certificate (*.example.com) or a SAN (Subject Alternative Names) certificate that explicitly includes them. Check that all domains your application uses are covered.

Expired certificates. Let's Encrypt certificates expire every 90 days. Certbot should auto-renew them, but auto-renewal requires correct cron/systemd configuration, correct web server configuration, and no port 80 blocking. Monitor certificate expiry — many monitoring services offer free certificate expiry alerts. An expired certificate breaks your site for all visitors and takes it offline as effectively as a DDoS attack.

Certificate Pinning: When and Why to Use It

Normal TLS certificate validation trusts any certificate issued by any CA in the browser's trust store (there are hundreds). This means that if any CA is compromised or issues a rogue certificate — which has happened multiple times historically — an attacker can perform a man-in-the-middle attack on your TLS connections with a certificate that browsers trust.

Certificate pinning takes a different approach: rather than trusting any CA-issued certificate for your domain, you specify exactly which certificate (or which CA) should be trusted for connections to your domain. Connections presenting any other certificate are rejected, even if that certificate is CA-signed.

In mobile apps (Android/iOS), certificate pinning is implemented by embedding the expected certificate hash in the app and verifying it against the server's certificate during the TLS handshake. We covered this in detail in the Android security post — it prevents proxy tools from intercepting app traffic even when they inject their own CA certificate.

For web browsers, HTTP Public Key Pinning (HPKP) was a browser-level certificate pinning header that has been deprecated due to the risk of misconfiguration permanently breaking sites. The current recommended web approach is Certificate Transparency monitoring rather than pinning.

For server-to-server communication (your PHP backend calling an external API), you should pin the expected certificate or CA when making HTTPS requests with cURL:

<?php
$ch = curl_init('https://api.yourpartner.com/data');

// Pin to the specific CA certificate
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/partner-ca-cert.pem');

// Or pin to a specific certificate hash (more strict)
curl_setopt($ch, CURLOPT_PINNEDPUBLICKEY, 'sha256//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // Never disable this in production
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // Verify hostname matches certificate

$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);

if ($error) {
    // Log the SSL error - don't expose it to users
    error_log('[cURL SSL Error] ' . $error);
    throw new RuntimeException('Failed to connect to partner API');
}

Never set CURLOPT_SSL_VERIFYPEER to false in production. This disables certificate verification entirely and makes your connection vulnerable to any man-in-the-middle attack. I see this frequently in PHP codebases where someone disabled verification to fix a certificate error during development and the change made it to production. The correct fix for certificate errors in development is to either install the certificate correctly or use a proper test certificate — not to disable verification.

Testing Your TLS Configuration

Before launching any HTTPS site, run it through SSL Labs' free server test at ssllabs.com/ssltest. It grades your TLS configuration and flags specific issues: supported protocol versions, cipher suites, HSTS configuration, certificate chain completeness, OCSP stapling, and more. Aim for an A or A+ grade.

Also run the Mozilla Observatory at observatory.mozilla.org — it tests HTTP security headers beyond just TLS, including Content Security Policy, X-Frame-Options, HSTS, and cookie security attributes.

TLS configuration is an area where the defaults on many hosting platforms aren't optimal and where a few configuration changes can meaningfully improve your security posture. The investment is small and the baseline protection it provides is significant.

— Skand K.

Share this article

Skand K. — Author
Written by

Skand K.

Senior Developer & Security Educator

Full-stack software engineer with 5+ years of experience in web development, mobile application architecture, and cybersecurity education. Passionate about teaching developers secure coding practices through hands-on, real-world projects. Contributor to open-source tools and author of educational guides on Telegram bot development, PHP frameworks, and Android security.