DevToys Web Pro iconDevToys Web Proบล็อก
ให้คะแนนเรา:
ลองใช้ส่วนขยายเบราว์เซอร์:
← Back to Blog

TLS/SSL Checker Guide: Versions, Certificates, and Cipher Suites

11 min read

Every HTTPS connection you make negotiates a TLS handshake before a single byte of application data is exchanged. The version of TLS chosen, the certificate the server presents, and the cipher suite agreed upon all determine how secure that connection actually is — yet most developers only notice these details when something breaks. Use the TLS Version Checker to inspect any host and follow along as this guide explains what you are looking at.

A quick note on terminology: "SSL" is the legacy name for the protocol family. SSL 2.0 and 3.0 are retired and broken; TLS 1.0, 1.1, 1.2, and 1.3 are the modern successors. The industry still uses "SSL certificate" as shorthand, but there is nothing SSL-specific about a modern certificate — it is an X.509 document that works with TLS. Wherever this guide says ssl checker or check ssl certificate, it means TLS.

TLS 1.2 vs TLS 1.3: What Actually Changed

TLS 1.3, finalized in RFC 8446 (2018), is a significant redesign, not an incremental patch. The most visible improvement is the handshake round-trip count, but the cryptographic changes run deeper.

Handshake latency

A TLS 1.2 full handshake requires two round trips before the client can send application data: one to negotiate parameters and one to exchange keys and finish. TLS 1.3 collapses this to one round trip (1-RTT) by sending key shares in the first message. For resumed connections it goes further: 0-RTT mode lets the client send application data immediately using a pre-shared key, though at the cost of replay-attack protection.

PropertyTLS 1.2TLS 1.3
Full handshake RTTs2-RTT1-RTT
RSA key exchangeSupported (static RSA)Removed
Forward secrecyOptional (DHE/ECDHE)Mandatory (always ECDHE or DHE)
RenegotiationSupportedRemoved
Legacy ciphers (RC4, 3DES)ConfigurableRemoved from spec
Cipher suite naming4-part string (e.g. ECDHE-RSA-AES128-GCM-SHA256)2-part string (e.g. TLS_AES_128_GCM_SHA256)

Why RSA key exchange removal matters

In TLS 1.2 with static RSA, the client encrypts the pre-master secret with the server's RSA public key. If an attacker records the encrypted traffic and later obtains the server's private key (through a breach, a court order, or a bug), they can retroactively decrypt every recorded session. TLS 1.3 removes static RSA entirely and requires ephemeral Diffie-Hellman, so each session's key material is discarded after use. This property is called forward secrecy: past sessions cannot be decrypted even if the long-term key is compromised later.

Renegotiation removed

TLS 1.2 allowed mid-connection renegotiation to change cipher parameters or re-authenticate. This mechanism was exploited in the 2009 renegotiation attack (CVE-2009-3555), patched imperfectly, and removed entirely in TLS 1.3. Post-handshake authentication in TLS 1.3 covers the legitimate use cases without the attack surface.

Reading a Certificate Chain

When a server presents a certificate, it does not stand alone. A valid TLS connection requires a chain of trust from the server's leaf certificate up to a root CA that the client trusts. There are three layers:

  • Leaf certificate — issued directly to your domain. Contains the public key used in the handshake, the subject (CN or SAN), and validity dates.
  • Intermediate certificate(s) — issued by the root CA to an intermediate CA, which then signs the leaf. Root CAs do not sign leaf certificates directly to limit exposure of the root private key. There may be one or two intermediates.
  • Root certificate — self-signed, pre-installed in the OS or browser trust store. The client trusts it unconditionally.

A missing intermediate is one of the most common TLS misconfigurations. The server must send the full chain (leaf plus all intermediates); it should not send the root, because the client already has it. If the intermediate is omitted, browsers usually recover by fetching it via the Authority Information Access (AIA) extension, but many non-browser TLS clients — mobile apps, CLI tools, IoT devices — do not implement AIA fetching and will reject the connection with a certificate verification error.

Use the Certificate Decoder to paste a PEM certificate and read the issuer, subject, SANs, and validity dates in a human-readable format.

Certificate Expiry, Validity Dates, and SANs

Every X.509 certificate has a notBefore and notAfter field. Browsers and TLS libraries reject certificates outside that window absolutely — there is no "expired but close enough" mode. An expired leaf certificate causes an immediate connection failure visible to end users as a browser warning.

Since 2020, the maximum certificate lifetime accepted by major browsers is 398 days (just over 13 months). Let's Encrypt issues 90-day certificates and recommends automated renewal at 60 days. If your monitoring checks expiry, alert at 30 days and again at 7 days; the 7-day window is short enough that an alert means act now.

The Subject Alternative Name (SAN) extension lists every hostname the certificate is valid for. The older Common Name (CN) field is ignored by modern browsers for hostname verification — only the SAN list matters. A wildcard SAN like *.example.com covers one level of subdomain (e.g. api.example.com) but not two levels (v2.api.example.com). If your hostname is not in the SAN list, the connection fails with a hostname mismatch error regardless of whether the certificate is otherwise valid.

What a Cipher Suite String Means

A TLS 1.2 cipher suite name like ECDHE-RSA-AES128-GCM-SHA256 is a four-part description of the algorithms used:

  • ECDHE — key exchange algorithm (Elliptic Curve Diffie-Hellman Ephemeral, providing forward secrecy)
  • RSA — authentication algorithm (the server's certificate type; RSA here means the certificate contains an RSA public key)
  • AES128-GCM — bulk cipher and mode (AES-128 in Galois/Counter Mode, an authenticated encryption scheme)
  • SHA256 — MAC/PRF algorithm (used in the handshake key derivation and record integrity)

TLS 1.3 simplified cipher suite naming because key exchange and authentication are no longer part of the suite — they are negotiated separately. A TLS 1.3 suite like TLS_AES_128_GCM_SHA256 specifies only the bulk cipher and hash function. This makes TLS 1.3 suite names shorter and removes the combinatorial explosion of TLS 1.2 suite variants. There are only five TLS 1.3 cipher suites defined in RFC 8446, compared to dozens in TLS 1.2.

Cipher SuiteVersionStatus
TLS_AES_128_GCM_SHA256TLS 1.3Recommended
TLS_AES_256_GCM_SHA384TLS 1.3Recommended
ECDHE-RSA-AES128-GCM-SHA256TLS 1.2Acceptable
ECDHE-RSA-AES256-CBC-SHA384TLS 1.2Acceptable (CBC less ideal)
RC4-SHA / RC4-MD5TLS 1.0/1.1/1.2Broken — disable immediately
DES-CBC3-SHA (3DES)TLS 1.0/1.1/1.2Deprecated — disable

Why TLS Checking Requires a Server-Side Probe

This is a question many developers ask: why can't a browser extension or a pure JavaScript page check TLS for an arbitrary host? The answer is a fundamental constraint of the web security model.

A browser tab runs in a sandboxed context and can only make HTTP/HTTPS requests via the fetch API or XMLHttpRequest — it cannot open a raw TCP socket. Even for requests it does make, the browser does not expose the negotiated TLS version or cipher suite to JavaScript. The TLS layer is handled by the browser's network stack below the JavaScript API boundary, and for good reason: if a page could read or influence the cipher negotiation of arbitrary hosts, that would open a new class of attacks.

Checking TLS therefore requires something that can open a raw TCP connection and speak the TLS handshake protocol directly. DevToys does this via a server-side route: when you submit a hostname in the TLS Version Checker, the request goes to a Next.js API route that connects to the target host, performs the TLS handshake, reads the negotiated parameters, and returns the results. No certificate data or hostname is stored; the probe is stateless and discards results after returning them.

Checking TLS With OpenSSL and curl

For local development, CI, or debugging production issues, openssl s_client is the standard command-line tool for TLS inspection. It connects to a host, performs the full handshake, and prints every detail.

# Full TLS handshake — shows certificate chain, cipher, protocol version
openssl s_client -connect example.com:443

# Force TLS 1.3 only (fails if server does not support it)
openssl s_client -connect example.com:443 -tls1_3

# Force TLS 1.2 only
openssl s_client -connect example.com:443 -tls1_2

# Show the full certificate chain
openssl s_client -connect example.com:443 -showcerts

# Check expiry date without interactive mode (pipe /dev/null to close connection)
openssl s_client -connect example.com:443 </dev/null 2>/dev/null \
  | openssl x509 -noout -dates

The output of openssl s_client includes a line like Protocol : TLSv1.3 and Cipher : TLS_AES_128_GCM_SHA256. The Verify return code: 0 (ok) line confirms the certificate chain validated successfully.

curl with verbose output is a quick alternative that also shows the TLS handshake details:

# Verbose output includes TLS version, cipher, and certificate info
curl -vI https://example.com

# Check a specific TLS version
curl -vI --tlsv1.3 https://example.com

# Ignore certificate errors (useful for testing self-signed certs — never in production)
curl -vI --insecure https://example.com

In curl -vI output, look for the line beginning with * SSL connection using — it shows the negotiated TLS version and cipher suite. A line like * Server certificate: begins the certificate summary.

Common TLS Misconfigurations

Expired or missing intermediate certificate

As covered in the chain section, omitting the intermediate certificate causes failures in strict clients. Equally common is an intermediate that has itself expired — this is less frequent since intermediates have multi-year lifetimes, but it does happen and produces confusing errors because the leaf certificate may appear valid in isolation.

TLS 1.0 and TLS 1.1 still enabled

TLS 1.0 and 1.1 were deprecated by RFC 8996 in 2021. All major browsers removed support in 2020-2021. PCI DSS has required TLS 1.2 or higher since 2018. Despite this, servers configured years ago may still advertise TLS 1.0/1.1 support. The risk is not theoretical: BEAST (a TLS 1.0 CBC weakness) and POODLE (primarily SSL 3.0, with an implementation-specific TLS variant) are known exploits. Disable both on your load balancer or web server and verify with the TLS Version Checker.

Weak or deprecated cipher suites

RC4 was broken by 2013 and is prohibited by RFC 7465. 3DES (Triple-DES) is vulnerable to the SWEET32 birthday attack and deprecated by NIST. Export-grade ciphers (40-bit or 56-bit keys) underlie the FREAK and Logjam attacks. Any modern cipher suite checker should flag these immediately. If your server lists any of these in its supported suites, remove them from the cipher string in your TLS configuration.

# Example: test which cipher suites a server accepts (requires nmap)
nmap --script ssl-enum-ciphers -p 443 example.com

Hostname mismatch

A certificate issued for www.example.com does not cover example.com unless both are listed as SANs. Similarly, a wildcard for *.example.com does not cover the apex domain example.com. Modern certificate issuers include both automatically, but older or manually-generated certificates often miss one. The TLS Version Checker reports the full SAN list so you can verify coverage.

Self-signed certificates in production

Self-signed certificates are appropriate for local development and internal services where you control all clients. In production or on any publicly-reachable service, they cause browser warnings and are rejected outright by most API clients unless certificate verification is explicitly disabled — a practice that defeats the purpose of TLS.

Server Configuration Examples

After diagnosing issues with the checker, you often need to update server configuration. Here are minimal secure TLS configurations for nginx and Apache.

# nginx — TLS 1.2 and 1.3 only, strong cipher suites
ssl_protocols TLSv1.2 TLSv1.3;
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_prefer_server_ciphers off;  # Let clients negotiate in TLS 1.3
# Apache — equivalent directives
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 off

After applying changes, re-run the TLS Version Checker to confirm TLS 1.0 and 1.1 no longer appear in the supported versions list and that no weak cipher suites remain.

If you need to inspect a certificate's contents in detail — issuer chain, OIDs, key usage extensions, and the raw ASN.1 structure — the Certificate Decoding Explained article walks through reading every field of an X.509 certificate and what each one means for trust and validation.


Check any hostname's TLS version, certificate chain, expiry, SANs, and cipher suites directly in your browser with the TLS Version Checker — the probe runs server-side so no certificate data is stored. For reading an individual certificate file, use the Certificate Decoder.