Skip to main content HTTPS | IoT Worker

HTTPS

The lock icon in the browser address bar is not just saying “this connection is encrypted”. HTTPS has to handle identity verification, key negotiation, transport protection, and handshake latency, and it has to do that at Internet scale.

HTTPS is often broken into separate topics like certificates, cipher suites, HTTP/3, and QUIC, and then only a pile of terms is left. Once the main line is pulled back together, the structure becomes clear: HTTPS is essentially HTTP over TLS. What matters is not that HTTP changed, but that HTTP now runs over a secure channel with authentication and key negotiation.

HTTPS does not just “encrypt HTTP content”. It first uses TLS to establish a secure connection with verifiable identity and negotiated keys, then layers the original HTTP semantics on top

Walk Through a Typical HTTPS Establishment

The most common HTTPS main path today is TCP + TLS 1.3 + HTTP/2, or further evolved into QUIC + TLS 1.3 + HTTP/3. If you only look at the TLS layer, the logic sequence can be compressed like this:

sequenceDiagram participant C as Client participant S as Server C->>S: ClientHello S->>C: ServerHello + Certificate + Finished C->>S: Finished C->>S: HTTP Request S->>C: HTTP Response

There are three goals behind that order:

  1. The client and server negotiate protocol version, cipher suite, and key exchange parameters
  2. The client verifies the server certificate and confirms who it is really connected to
  3. Both sides derive session keys from the handshake so later HTTP data can travel over an encrypted channel

If you only think of HTTPS as “encrypted HTTP”, many later symptoms stop making sense, such as:

  • Why certificate problems can stop the business request entirely
  • Why TLS 1.3 packet captures show very little plaintext after the handshake begins
  • Why 0-RTT reduces latency but cannot be used freely for every request

Why HTTPS Had to Appear

HTTP itself only defines resource semantics and request/response behavior. It does not solve three risks on the open Internet:

  • Middleboxes can see the content in clear text
  • The client cannot prove server identity using HTTP alone
  • A path attacker can alter the response without being easily noticed

These cannot be fixed by simply adding a few business fields. They happen before HTTP semantics are even safely in effect. If the client has not yet confirmed the peer identity, it cannot safely send cookies, passwords, tokens, or business data.

TLS solves more than confidentiality:

  • Authentication: certificate chains and hostname validation confirm server identity
  • Integrity: transport data cannot be silently altered
  • Key negotiation: the two sides establish a secure channel without pre-sharing a session key
  • Evolution: protocol versions, cipher suites, and extensions can still be negotiated and upgraded

Keep the Object Boundaries Clear

HTTP, TLS, HTTPS, and QUIC are often discussed together, but their responsibilities are not the same:

  • HTTP defines resource semantics, methods, status codes, caching, and intermediaries
  • TLS handles authentication, key negotiation, and transport protection
  • HTTPS is the deployment result of putting the first two together
  • QUIC is another transport protocol that uses TLS 1.3, but is not the same thing as “a secure version of HTTPS”

If you treat TLS and QUIC as if they were three parallel “security protocols used by HTTPS”, the classification is already off. TLS 1.2 and TLS 1.3 are the security protocol versions directly depended on by HTTPS. QUIC is the transport-layer scheme used by HTTP/3, and it reuses TLS 1.3 handshake and key derivation.

What TLS 1.2 Solved, and Where It Hurt

TLS 1.2 supported mainstream HTTPS for a long time, but its main path had two obvious costs: more round trips and more plaintext exposure during the handshake.

sequenceDiagram participant C as Client participant S as Server Note over C,S: RTT 1 C->>S: ClientHello S->>C: ServerHello + Certificate + ServerKeyExchange + ServerHelloDone Note over C,S: RTT 2 C->>S: ClientKeyExchange + ChangeCipherSpec + Finished S->>C: ChangeCipherSpec + Finished

That path feels heavy because:

  • A complete handshake usually takes 2-RTT
  • More of the handshake is visible in clear text
  • Cipher suite history adds compatibility baggage
  • Forward secrecy is not automatically enforced in older deployments

TLS 1.2 was not wrong. It balanced compatibility and security for an earlier deployment reality. But as web services became more dependent on mobile networks and the global Internet, handshake latency and complexity started to matter much more.

Why TLS 1.3 Looks Like This

TLS 1.3 is not just “update a parameter table”. It removes long-standing pain points:

  • Common handshakes are reduced to 1-RTT
  • Plaintext exposure during the handshake is minimized
  • Key exchange is forced toward forward-secure choices
  • Many historical weak algorithms and compatibility layers are removed

The main path is much shorter:

sequenceDiagram participant C as Client participant S as Server Note over C,S: RTT 1 C->>S: ClientHello + key_share S->>C: ServerHello + {EncryptedExtensions + Certificate + CertificateVerify + Finished} C->>S: {Finished} + HTTP Request S->>C: HTTP Response

The main changes are:

First, the client includes key_share directly in ClientHello. The client is no longer only asking what the server supports. It also brings key-exchange material early to reduce round-trip probing.

Second, after ClientHello and ServerHello, the rest of the handshake moves into encrypted state as early as possible. When you capture packets, you often see a block of Application Data. That is not because the handshake disappeared. It is because it is already protected.

Third, the cipher-suite responsibilities are narrowed. TLS 1.3 no longer binds a bunch of historical algorithms into complicated combinations. It draws the boundaries between AEAD, hash, and key exchange more clearly, which reduces compatibility sludge.

What to Watch in Debugging

Handshake diagrams explain sequence, but they are not enough to support implementation and troubleshooting. When capturing HTTPS packets, the most useful questions are usually these.

First check whether the connection reached TLS 1.3

Common clues include:

  • Does supported_versions include TLS 1.3
  • Did ServerHello actually select TLS 1.3
  • Did the later handshake messages move into encrypted form quickly

If the negotiation fell back to TLS 1.2, the next step is usually server configuration, old-client compatibility, or middlebox interference.

Then check whether the certificate and hostname match

Many “HTTPS will not connect” incidents are not encryption failures at all. They are identity-validation failures:

  • The certificate chain is incomplete
  • The certificate has expired
  • The hostname does not match the certificate SAN
  • The client does not trust the issuing CA

The result is direct: the HTTP request never reaches the normal business stage.

Finally check where the handshake stopped

In troubleshooting, first ask:

  1. Was ClientHello sent
  2. Did ServerHello and the certificate come back
  3. Did the client continue with Finished after validation

If the first step never happened, the problem is more likely network reachability, port listening, or a lower-layer transport failure. If the second step is missing, it is more likely a server, load balancer, or middlebox issue. If the certificate came back but the client did not continue, validation likely failed or a policy rejected it.

What 0-RTT Solves, and What It Costs

TLS 1.3 also provides 0-RTT, but it is not “a faster normal handshake”. It is a special optimization for session resumption.

sequenceDiagram participant C as Client participant S as Server C->>S: ClientHello + PSK + Early Data S->>C: ServerHello + Finished C->>S: Finished

The problem it solves is clear: if the client and server have already established a session before, the next time the client can send part of the application data before the handshake fully finishes, which reduces the first-request wait.

The cost is also clear:

  • 0-RTT data is replayable
  • It does not have the same security semantics as normal 1-RTT data
  • The server needs extra anti-replay and policy control

A common engineering default is:

  • Use 0-RTT only for session resumption
  • Only allow idempotent requests to go early, such as GET or HEAD
  • Do not let state-changing requests use 0-RTT by default

Where HTTP/3 and QUIC Belong

With HTTP/3, the layout changes: HTTP no longer runs on TCP + TLS. It runs on QUIC + TLS 1.3. The easiest thing to confuse here is whether TLS is still present.

It is.

It just no longer sits as an independent wrapper above TCP. It is embedded in QUIC’s connection establishment. The relationship is simple enough if you keep this picture in mind:

HTTP/1.1 / HTTP/2: TCP + TLS + HTTP
HTTP/3: QUIC(contains TLS 1.3 handshake) + HTTP

If the topic is HTTPS, this is where the main line can stop. QUIC has its own problem space:

  • Why it wants to escape TCP head-of-line blocking
  • Why it introduces Connection ID
  • Why connection migration and stream-level recovery change HTTP behavior

Those are worth a separate article instead of being squeezed into the TLS main line.

What to Check in Implementation and Troubleshooting

  • First confirm which layer the problem belongs to: HTTP semantics, TLS handshake, or the lower TCP / QUIC connection
  • First check whether version negotiation completed before diving into certificate and hostname validation
  • Seeing many encrypted handshake messages in TLS 1.3 captures is normal. It does not mean Wireshark “failed to decode”
  • When you hit a latency problem, first separate TCP connection cost, TLS handshake cost, and the HTTP request itself
  • When evaluating 0-RTT, ask whether the request is idempotent first. Do not treat “fewer round trips” as unconditional benefit

Appendix: Quick Reference

Main differences between TLS 1.2 and TLS 1.3

Dimension TLS 1.2 TLS 1.3
Common handshake cost 2-RTT 1-RTT
Handshake plaintext exposure More Less
Forward secrecy Depends on suite and deployment Tightened by default
0-RTT Not supported Supported for session resumption
Best way to think about it Historical compatibility path Current mainstream path

Minimum packet-capture checkpoints

Checkpoint What to look for
ClientHello Supported versions, SNI, ALPN, key_share
ServerHello Final negotiated version and key parameters
Certificate Certificate chain, validity, hostname match
Finished Whether both sides really completed the handshake

Further Reading

  • TCP - why the transport layer affects handshake and latency in TCP + TLS
  • QUIC - the transport layer, multiplexing, and migration used by HTTP/3
  • HTTP - the request/response semantics carried under HTTPS

References

  • RFC 5246: TLS 1.2
  • RFC 8446: TLS 1.3
  • RFC 9001: Using TLS to Secure QUIC
  • RFC 9114: HTTP/3