Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

TLS 1.2 vs TLS 1.3

By Kokil Thapa | Last reviewed: September 2026

Choosing between TLS 1.2 vs TLS 1.3 is no longer a theoretical debate on most production stacks. Browsers, payment gateways, and API clients already prefer 1.3. Your job is to understand what changed, what breaks, and how to configure Apache or Nginx without leaving older clients stranded. This guide walks through handshake mechanics, cipher policy, and copy-paste server config grounded in real Linux server administration work on client sites in Nepal and abroad.

What is the difference between TLS 1.2 and TLS 1.3?

Both versions encrypt HTTP, API traffic, and database tunnels. The practical gap is how they negotiate keys and which algorithms they allow. TLS 1.2, defined in RFC 5246, supports many cipher suites. Some are strong. Some are obsolete today.

TLS 1.3, defined in RFC 8446, trims the cipher list aggressively. It drops RSA key transport, static Diffie-Hellman, CBC-mode bulk ciphers, and several legacy MAC constructions. Forward secrecy becomes the default path, not an optional upgrade.

TLS 1.2 vs TLS 1.3 Feature MapTLS 1.2 (RFC 5246)RSA key exchange allowedCBC ciphers + SHA-1 MAC2-RT full handshakeRenegotiation supportedTLS 1.3 (RFC 8446)Ephemeral key exchange onlyAEAD ciphers (AES-GCM, CHACHA)1-RT full handshakeEncrypted handshake metadata1.3 removes weak options; 1.2 kept them for compatibility
Side-by-side TLS 1.2 vs TLS 1.3: what stayed, what was removed, and why 1.3 is the safer default in 2026.

On legal-tech portals and eCommerce sites I maintain, the shift matters beyond benchmarks. Faster handshakes reduce time-to-first-byte on mobile networks in Kathmandu. Stricter ciphers reduce the attack surface PCI assessors and security scanners flag during audits. For background on certificates themselves, see the guide on SSL/TLS certificates explained.

Core protocol changes at a glance

  • Cipher suites: TLS 1.3 defines five mandatory suites. TLS 1.2 allows dozens, including weak ones if you misconfigure the server.
  • Key exchange: 1.3 requires (EC)DHE. RSA encryption of premaster secrets is gone.
  • Handshake shape: 1.3 sends encrypted extensions earlier. More of the negotiation is confidential.
  • 0-RTT: Only 1.3 supports early data resumption. Useful for speed, risky if replay is possible.
  • Session resumption: 1.3 uses PSK-based tickets instead of older session-ID patterns in many stacks.

How does the TLS 1.3 handshake compare to TLS 1.2?

Latency is where engineers feel the difference first. A full TLS 1.2 handshake needs two round trips before application data flows. TLS 1.3 completes the full handshake in one round trip under normal conditions. On high-latency mobile links, that single RTT saving often beats shaving kilobytes off HTML.

The detailed message flow is covered in the TLS 1.3 handshake explained. Here is the operational summary you need when tuning production servers.

Handshake Round Trips: TLS 1.2 vs 1.3TLS 1.2 — 2 RT full handshakeClientServerClientHelloServerHello + cert (RT 1)Finished (RT 2)TLS 1.3 — 1 RT full handshakeClientServerClientHello + key shareServerHello + FinishedResumed connection (both versions)TLS 1.3 0-RTT: client sends early app data with resumption PSK0-RTT is replayable — disable on POST/payment routesTLS 1.2 resume: typically 1 RT with session tickets
TLS 1.3 cuts full-handshake latency by one network round trip compared with TLS 1.2 on the same path.

When 0-RTT helps and when it hurts

0-RTT lets repeat visitors send HTTP requests before the handshake finishes. That sounds ideal for static assets and read-heavy pages. It is a poor fit for anything that changes state. Payment callbacks, login forms, and booking endpoints on sites like Adventure Third Pole Trek must treat 0-RTT as unsafe unless the application layer implements anti-replay logic.

Most small Laravel and WordPress stacks simply disable 0-RTT at the web server. The speed gain from 1-RTT full handshakes is already meaningful. You avoid a whole class of replay bugs.

Which cipher suites should you allow in TLS 1.2 vs TLS 1.3?

Cipher policy is the second place TLS 1.2 vs TLS 1.3 diverges in production config files. With 1.3, the server advertises a short list. OpenSSL and Nginx map them to names like TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256. You mostly choose order, not membership.

With 1.2, you own the full allowlist. A permissive string like HIGH:!aNULL still lets through configurations that fail modern audits. I standardise on ECDHE key exchange, AEAD bulk encryption, and disable CBC where possible.

CriterionTLS 1.2TLS 1.3
Typical bulk cipherAES-GCM, ChaCha20-Poly1305 (if configured)AES-128/256-GCM, ChaCha20-Poly1305 only
Key exchangeRSA, DHE, ECDHE (config-dependent)(EC)DHE only — forward secrecy by default
Hash for PRF/MACSHA-256, SHA-384, legacy SHA-1 in old suitesSHA-256 / SHA-384 built into AEAD suites
Misconfiguration riskHigh — many obsolete suites remain availableLow — small fixed set
PCI / scanner postureRequires tight cipher string disciplinePasses most checks with version enabled
Interop with old AndroidRequired for Android 4.x–6.x without patchesAndroid 10+ native; older need 1.2 fallback

For password and key material handling in adjacent workflows, pair transport security with strong secrets generated via a password generator tool. TLS protects data in motion. It does not fix weak credentials at rest.

How do you configure Nginx and Apache for TLS 1.2 and TLS 1.3?

Your OpenSSL build must support 1.3. On Ubuntu 22.04 and 24.04 with system OpenSSL 3.x, it does. Verify with:

openssl version -a
nginx -V 2>&1 | grep -i openssl

Full Nginx guidance lives in TLS 1.3 vs 1.2 configuration for Nginx. Below is a baseline I deploy on Apache + PHP-FPM stacks serving Laravel 12 and WordPress 7.1 sites.

Nginx example (dual-stack, 1.3 preferred)

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    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_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    add_header Strict-Transport-Security "max-age=63072000" always;
}

Note ssl_prefer_server_ciphers off with TLS 1.3. Clients pick AEAD suites correctly. For 1.2-only clients, the cipher string still enforces ECDHE and GCM.

Apache example (mod_ssl on Ubuntu)

<VirtualHost *:443>
    ServerName example.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
                     ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder on

    Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>

After any SSL change, reload the daemon and verify live negotiation. I use Qualys SSL Labs for external perspective and openssl s_client locally:

openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>/dev/null | grep "Protocol"
openssl s_client -connect example.com:443 -tls1_2 </dev/null 2>/dev/null | grep "Cipher"

Sister sites on shared EC2 infrastructure — notary portals, translation services — share a Deployer 7 pipeline. Certbot renews certificates on schedule. PHP-FPM reload follows symlink swaps so opcache picks up code changes. TLS config lives in the web server layer and rarely changes per deploy. Details sit in Ansible playbooks for PHP server provisioning when I automate new hosts.

TLS Termination on a Typical Laravel StackBrowserTLS 1.3 preferNginxCert + cipher policyHTTP/2 or HTTP/1.1PHP-FPM 8.3+Plain HTTP locallyMySQL 8.4TLS optionalFallback path if client lacks TLS 1.3Browser negotiates TLS 1.2 with ECDHE-GCM cipherTLS 1.0/1.1 disabled — no negotiation possible
Typical production flow: TLS terminates at Nginx; PHP-FPM and MySQL run on trusted internal paths behind the edge.

Should you disable TLS 1.2 and run TLS 1.3 only?

For most public websites in 2026, keep both enabled for now. Disable SSLv3, TLS 1.0, and TLS 1.1 unconditionally. Those versions fail compliance and browser trust policies.

TLS 1.3-only makes sense in controlled environments: internal gRPC meshes, service-to-service APIs where you own every client, or greenfield mobile apps with modern SDKs. Public law-firm portals and WooCommerce stores still see occasional 1.2-only clients. Disabling 1.2 without analytics to back the decision generates support tickets.

Decision checklist before dropping TLS 1.2

  1. Pull thirty days of access logs and tag TLS version if your edge logs ssl_protocol or equivalent.
  2. Check payment gateway and bank API requirements. Some specify minimum TLS versions but not maximum.
  3. Run SSL Labs and fix 1.2 cipher weaknesses first. A tight 1.2 stack beats a sloppy 1.3-only headline.
  4. Schedule the change outside Dashain/Tihar peaks if you serve Nepal retail traffic.
  5. Document rollback: keep the previous config snippet in your support and maintenance runbook.

Load-balanced setups add another layer. HAProxy and Kubernetes ingress controllers each expose protocol knobs differently. See HAProxy load balancing config and TLS and Kubernetes ingress and TLS with cert-manager when TLS terminates before your PHP workers.

When to Keep TLS 1.2 EnabledPublic website or store?YesKeep 1.2 + 1.3Tight ECDHE-GCM ciphersNoInternal API only?Log review firstAny 1.2 clients left?Yes → keep 1.2No → 1.3 only OKNever enable TLS 1.0 or 1.1 on any public endpoint in 2026
Decision flow for TLS 1.2 vs TLS 1.3-only: public sites need fallback; internal APIs can drop 1.2 after log proof.

Sites handling sensitive documents — client portals like Mijar Law Associates or Notary Nepal — benefit from HSTS preload and modern TLS together. Transport security is one layer. Application auth, rate limiting, and upload validation still matter. Read API rate limiting and abuse prevention for the next layer up.

What performance and SEO impact does TLS 1.3 have?

Search engines rank on Core Web Vitals, not TLS version directly. Indirect effects are real. Faster handshakes improve TTFB on cold connections. Mobile users on 4G in Nepal feel one fewer RTT on first visit. HTTP/2 and HTTP/3 adoption also pairs naturally with modern TLS stacks configured during speed optimization work.

Certificate overhead dominates on asset-heavy pages with many third-party domains. Each new origin may negotiate TLS separately. Keep asset domains on the same cert where possible. Use session tickets consistently. For greenfield apps, consider web development patterns that consolidate static delivery behind one edge hostname.

Testing belongs in staging before production cutover. A mis-ordered cipher string or missing intermediate certificate breaks more traffic than upgrading from 1.2 to 1.3. Fold SSL checks into your testing and optimization checklist alongside PHP 8.3+ and Laravel 13 readiness reviews.

Key Takeaways

  • Prefer TLS 1.3 everywhere; keep TLS 1.2 as a fallback on public sites until logs prove zero legacy clients.
  • Disable TLS 1.0 and 1.1 today — they carry no upside and fail audits.
  • Lock TLS 1.2 to ECDHE + AEAD ciphers; let TLS 1.3 handle its own short suite list.
  • Disable 0-RTT on state-changing routes unless you implement explicit anti-replay controls.
  • Verify with openssl s_client and SSL Labs after every config change, not just at launch.
  • Terminate TLS at a maintained edge (Nginx/Apache/HAProxy) and automate cert renewal with Certbot or cert-manager.

People Also Ask

Is TLS 1.3 backward compatible with TLS 1.2?

Clients and servers negotiate the highest mutually supported version. A browser that speaks 1.3 connects with 1.3. An older client falls back to 1.2 if the server still allows it. They do not share cipher suites — 1.3 suites are version-specific.

Does Let's Encrypt support TLS 1.3?

Let's Encrypt issues certificates, not protocol versions. Your web server chooses TLS versions. Certbot-managed certs work with both 1.2 and 1.3 once OpenSSL and Nginx or Apache are current.

Which browsers require TLS 1.2 minimum?

All mainstream browsers in 2026 require at least TLS 1.2. Chrome, Firefox, Safari, and Edge have supported TLS 1.3 for years. Legacy Internet Explorer and unpatched Android WebViews are the usual reasons to keep 1.2 fallback.

Is TLS 1.2 still secure in 2026?

TLS 1.2 remains acceptable when weak ciphers and RSA key transport are disabled. PCI DSS and industry guidance treat 1.2 as minimum for compatibility. TLS 1.3 is the recommended target for new deployments because the protocol removes risky options by design.

Deploy modern TLS with confidence

The TLS 1.2 vs TLS 1.3 choice is really about defaults: enable 1.3, tighten 1.2, and retire everything below. Measure before you disable fallback. Automate certificate renewal. Reload your web server after every change.

If you want help auditing SSL on a live Laravel, WordPress, or WooCommerce stack — including Certbot, HSTS, and cipher hardening on Ubuntu — see domain registration and hosting or reach out via contact us. For broader context on how I approach production systems, visit about me or browse the portfolio of deployed sites.

Frequently Asked Questions

TLS 1.3 is faster (one RTT handshake), removes weak ciphers and RSA key exchange, and encrypts more negotiation. TLS 1.2 supports many suites, some obsolete if misconfigured.

A full TLS 1.2 handshake needs two round trips before application data flows. TLS 1.3 completes the full handshake in one round trip under normal conditions. On high-latency mobile links, that single RTT saving often beats shaving kilobytes off HTML. TLS 1.3 also sends encrypted extensions earlier, so more of the negotiation stays confidential. Only TLS 1.3 supports 0-RTT early data resumption, which can speed repeat visits but introduces replay risk on state-changing requests.

Yes. Clients negotiate the highest version both sides support. Modern browsers use TLS 1.3; older clients fall back to TLS 1.2 if enabled. Cipher suites differ between versions.

For most public websites in 2026, keep both TLS 1.2 and TLS 1.3 enabled. TLS 1.3-only makes sense in controlled environments such as internal gRPC meshes, service-to-service APIs where you own every client, or greenfield mobile apps with modern SDKs. Public law-firm portals and WooCommerce stores still see occasional TLS 1.2-only clients. Before dropping 1.2, pull thirty days of access logs tagged by TLS version, check payment gateway requirements, run SSL Labs, and document rollback steps in your maintenance runbook.

TLS 1.3 defines five mandatory suites such as TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256; you mostly choose order, not membership. TLS 1.2 allows dozens of suites, and a permissive string like HIGH:!aNULL can still pass weak configurations that fail audits. Standard practice is ECDHE key exchange, AEAD bulk encryption, and disabling CBC where possible. TLS 1.3 requires (EC)DHE only, making forward secrecy the default. Misconfiguration risk is high on TLS 1.2 and low on TLS 1.3 because the allowed set is small and fixed.

Your OpenSSL build must support TLS 1.3; Ubuntu 22.04 and 24.04 with system OpenSSL 3.x does. Verify with openssl version -a and nginx -V. On Nginx, set ssl_protocols TLSv1.2 TLSv1.3, ssl_prefer_server_ciphers off, and an ECDHE plus GCM cipher string for 1.2 clients. On Apache mod_ssl, use SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 with a matching ECDHE-GCM SSLCipherSuite. After any change, reload the daemon and test live negotiation before treating the site as production-ready.

Let's Encrypt issues certificates, not protocol versions. Your web server chooses TLS versions. Certbot-managed certs work with both 1.2 and 1.3 on current OpenSSL, Nginx, or Apache.

Yes, if weak ciphers and RSA key transport are disabled. PCI treats 1.2 as minimum for compatibility. TLS 1.3 is the recommended target for new deployments.

0-RTT lets repeat visitors send HTTP requests before the handshake finishes, which helps static assets and read-heavy pages. It is a poor fit for anything that changes state. Payment callbacks, login forms, and booking endpoints must treat 0-RTT as unsafe unless the application implements anti-replay logic. Most small Laravel and WordPress stacks disable 0-RTT at the web server. The speed gain from a one-RTT full handshake in TLS 1.3 is already meaningful, and disabling 0-RTT avoids a whole class of replay bugs.

All mainstream browsers in 2026 require at least TLS 1.2. Chrome, Firefox, Safari, and Edge have supported TLS 1.3 for years. Legacy Internet Explorer and unpatched Android WebViews are the usual reasons to keep TLS 1.2 as a fallback on public sites. Android 4.x through 6.x without patches also depends on TLS 1.2 because it cannot negotiate TLS 1.3 natively.

Search engines rank on Core Web Vitals, not TLS version directly, but faster handshakes improve time-to-first-byte on cold connections. Mobile users on 4G in Nepal feel one fewer round trip on first visit. HTTP/2 and HTTP/3 pair naturally with modern TLS stacks. Certificate overhead dominates on asset-heavy pages with many third-party domains, because each new origin may negotiate TLS separately. Keep asset domains on the same certificate where possible and use session tickets consistently. Test in staging before production cutover.

Reload your web server after every SSL change, then verify live negotiation rather than assuming the config file is correct. Use Qualys SSL Labs for an external perspective. Locally, run openssl s_client against port 443 with -tls1_3 and -tls1_2 flags and inspect the reported Protocol and Cipher lines. A mis-ordered cipher string or missing intermediate certificate breaks more traffic than upgrading from TLS 1.2 to TLS 1.3, so fold these checks into your staging and production testing checklist.

TLS 1.3 drops RSA key transport and static Diffie-Hellman, requiring (EC)DHE for key exchange instead. That makes forward secrecy the default path rather than an optional upgrade. Without forward secrecy, an attacker who records encrypted traffic and later obtains the server private key can decrypt past sessions. TLS 1.2 still allows RSA and other legacy key exchange methods if the server cipher string is too permissive. TLS 1.3 removes those risky options by design, which is why it passes most PCI and security scanner checks with less manual tuning.

Keep TLS 1.2 enabled while legacy clients still connect and until access logs prove zero need for it. Public law-firm portals, WooCommerce stores, and similar sites still see occasional TLS 1.2-only clients from older Android devices and unpatched WebViews. Android 4.x through 6.x without patches requires TLS 1.2 fallback. Schedule any change to disable 1.2 outside peak retail periods if you serve Nepal traffic, and always keep a documented rollback config snippet ready.

Disable SSLv3, TLS 1.0, and TLS 1.1 today. Those versions carry no upside and fail compliance checks and browser trust policies. On Apache, use SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1. On Nginx, omit those protocols from ssl_protocols and allow only TLSv1.2 and TLSv1.3. Retire everything below TLS 1.2 regardless of whether you eventually move to TLS 1.3-only. A tightly configured TLS 1.2 stack beats a sloppy TLS 1.3-only headline that breaks older clients without a measured reason.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: