Skip to content
JackSparrow414
Go back

Understanding HTTPS, TLS, and SSL (Part 1): Core Concepts and Local Self-Signed Certificates

Table of contents

Open Table of contents

Article body

I often encounter HTTPS, TLS, and SSL. After reading a few articles, I used to think I understood them, but I did not. I want to fill in this foundational knowledge, without going deeply into subjects such as interpreting the various standards.

What Things Look Like Without HTTPS

We know that HTTP is insecure and why. To make this more concrete and deepen my understanding, I built a simple demonstration using Wireshark.

Demonstration Setup

Create a simple local RESTful Java project and deploy it to Tomcat.

Wireshark Capture Filters and Display Filters

Set a Capture Filter

We only want local packets, so select Loopback in the interface and set the capture filter before starting.

src host localhost and dst host localhost

Setting a capture filter for the loopback interface on the Wireshark welcome page Press Enter to start capturing.

Find capture filter syntax through Wireshark > Help > Wiki > CaptureFilters > Further Information (pcap-filter man page), which provides the full syntax.

Start the Application

Start the test application locally. Configure only the HTTP port in IntelliJ IDEA’s Tomcat settings; mine is 8080.

Send a POST request from the terminal.

curl -X POST http://localhost:8080/validation/valid/inline/post

Filter Captured Packets with a Display Filter

Set the display filter.

http and tcp.port eq 8080

Wireshark capturing HTTP traffic and showing the plaintext request For display filter syntax, see:

Conclusion

The demonstration can be summarized as follows: HTTP sends everything in the clear. Data travels over the network as plaintext. Packet-capture tools can intercept it, and it may even be modified. The consequences are alarming: people interacting with online services can easily have their private information exposed.

A Clearer Explanation of Why Encryption Matters

To address plaintext communication, we must encrypt it and deal with man-in-the-middle attacks.

For a more precise explanation of why encryption is needed, see Cloudflare’s article. The following points are translated from its Chinese version:

  1. Privacy: encryption ensures that communications and stored data can only be read by the intended recipient or legitimate owner. It protects privacy by preventing attackers, advertising networks, internet service providers, and sometimes governments from intercepting and reading sensitive information.

  2. Security: encryption helps prevent data breaches both in transit and at rest. If a company device is lost or stolen and its hard drive is properly encrypted, its data remains protected. Encrypted communication similarly allows parties to exchange sensitive information without exposing it.

  3. Data integrity: encryption also helps prevent malicious activity, such as attacks on data in transit. When data travels over the internet, encryption helps ensure that what arrives has not been viewed or altered along the way.

  4. Regulations: for these reasons, many industry and government rules require companies to encrypt user data. Examples of regulations and compliance standards requiring encryption include HIPAA, PCI-DSS, and GDPR.

Symmetric Encryption, Asymmetric Encryption, and CA Certificates

Key Exchange

How do we address man-in-the-middle attacks? The CA certificate section below explains.

Symmetric Encryption

Symmetric encryption uses one key for both encryption and decryption.

That is its drawback: anyone who obtains the key can both decrypt and encrypt information.

Asymmetric Encryption

Certificate Authorities and Certificates

Both symmetric and asymmetric encryption face the same question: how do we prevent man-in-the-middle attacks?

A trusted third party is introduced for this purpose. Here is the explanation from the keytool documentation:

In a large-scale networked environment, it is impossible to guarantee that prior relationships between communicating entities were established or that a trusted repository exists with all used public keys. Certificates were invented as a solution to this public key distribution problem. Now a Certification Authority (CA) can act as a trusted third party

A CA’s main role is to assure the client that it is communicating with the intended server, rather than an attacker impersonating it.

But another question arises: if an attacker can impersonate a server, why not impersonate the CA?

How Is Trust Between the Client and the CA Established?

When a CA returns a certificate, the client uses the CA’s public key to verify that its digital signature was genuinely issued by that CA. But are there not many CA public keys too?

This raises a few questions:

  1. Wait—is this another client/server problem, with the CA as the server? To avoid endless recursion, certificates containing CA public keys are installed in the operating system by default. There are relatively few CAs, so they can be included in advance.
  2. For more detail, see this answer on man-in-the-middle attacks with CA certificates and asymmetric encryption, which explains why a man-in-the-middle attack against the CA is unlikely.
  3. This also explains why asymmetric encryption is used at this stage. With symmetric encryption, anyone who cracked the CA’s key could impersonate it, with disastrous consequences.

Generate a Key Pair and Self-Signed Certificate with Java keytool

A quick command:

keytool -h

The following command generates a key pair and a self-signed certificate.

keytool -genkey -alias tomcat -keyalg RSA

genkey and genkeypair are equivalent.

The command uses the default SHA256withRSA signature algorithm to create a self-signed certificate that includes the public key and the distinguished name information. The certificate is valid for 180 days

The default filename is .keystore. From the keytool documentation:

For example, if keytool -genkeypair is called and the -keystore option isn’t specified, the default keystore file named .keystore is created in the user’s home directory if it doesn’t already exist

Generate Them with KeyStore Explorer

Besides keytool, I usually use KeyStore Explorer to generate them through its graphical interface. There are too many commands to remember, and a few mouse clicks are more convenient. Key and certificate entry created in KeyStore Explorer

The Difference Between .pem and .p12 Files

See this Stack Overflow answer on PEM, CRT, and KEY files.

PEM is a file format and can store different kinds of content.

In practice, a .pem file typically contains a public key, while a .p12 file typically contains a public key, private key, and certificate.

Configure TLS/SSL in Tomcat

Complete official Tomcat SSL configuration guide

SSL Still Does Not Work After Configuring a Self-Signed Certificate

After restarting Tomcat, visiting https://localhost:8443/validation/ in the browser still produces this warning: Browser showing an untrusted certificate warning when accessing local HTTPS For a self-signed certificate, import it into the appropriate operating-system store.

  1. Export the self-signed certificate.
    keytool -export -alias tomcat -keystore .keystore -file tomcat.cer
  2. On macOS, open Keychain Access, drag the exported certificate into it, double-click the certificate, expand Trust, and set the trust level to Always Trust. Setting a self-signed certificate to Always Trust in macOS Keychain Access
  3. Restart Tomcat and access it through HTTPS. Chrome now says the certificate does not contain a Subject Alternative Name, although Safari works normally.

Fix Chrome’s Missing Subject Alternative Name Warning

After looking into this, I found that a self-signed certificate needs SubjectAlternativeName configured.

Delete the key and exported certificate generated earlier, then generate them again.

keytool -genkey -alias tomcat -keyalg RSA -ext san=IP:127.0.0.1,DNS:localhost

For the complete san syntax, see the supported named extensions section of the keytool documentation

After generating the certificate, export it again, add it to the appropriate operating-system store, and trust it. Restart Tomcat and revisit https://localhost:8443/validation/. Browser accessing the local HTTPS page and showing secure connection information This time, the expected 🔐 icon appears.

What Things Look Like with HTTPS

With HTTPS configured, capture packets with Wireshark again.

This time, send an HTTPS request.

curl -X POST -k https://localhost:8443/validation/valid/inline/post

Packets Captured by Wireshark

tls and tcp.port in {8443, 55026}

Wireshark HTTPS packets showing only encrypted application data The captured packets are now encrypted. The plaintext data is no longer visible.

Also note that TLS encryption hides the entire HTTP request, including the HTTP URL. Compare this with the first screenshot in the post.

Further Thoughts: Is Frontend/Client/Browser Request Encryption Necessary?

Here, frontend encryption means encrypting a user’s password before submitting a login request to the backend. This is widely debated on technical websites; I will give only my own understanding.

First, there are three places where encryption occurs in an HTTP request:

  1. Client-side encryption, before submitting the request.
  2. Transport encryption: HTTPS.
  3. Server-side encryption: developers with some experience know that passwords are stored using a method such as hash(password + salt).

For a developer with some experience, such as myself, who knows how server-side encryption works and that HTTPS encrypts all HTTP content, my answer is: I do not think frontend encryption is necessary.

My reasons are:

  1. Encryption before request submission cannot stop scripts in malicious browser extensions. They can listen to keyboard events or inspect HTML elements and obtain the plaintext password before the request is submitted.
  2. Even if the password is appended to the URL, the example above shows that HTTPS encrypts the entire HTTP content. With HTTPS supported, the transport is secure, so this concern can be disregarded.
  3. Many large companies also submit passwords as plaintext. Perhaps try persuading their engineers first?

Common arguments:

  1. What if I enter my password, step away from the computer, and someone opens developer tools with F12? I think this is why many people use frontend encryption. In my view, 2FA or passkeys can address this scenario. If your company cannot support those approaches, I would leave it there. This offers only a limited deterrent, rather than protection against a determined attacker; I will not explore it further.
  2. What about the request body? On some sites, F12 reveals it; on others, it does not. I think this may be intended to deter scrapers. If scraping is a problem, try rate limiting, blocklists, or similar measures. I have little experience in this area, so I will not expand on it. As above, it is a limited deterrent against determined attackers.

My view is that any technical decision must consider the team’s staffing and familiarity with its stack, costs, benefits, and other complex factors.

Final Thoughts

This post organizes my questions and thoughts about TLS, public and private keys, and CA certificates.

The next post analyzes the TLS handshake in detail.

References

  1. The Java keytool documentation, especially Terms, which explains keystores, entries, aliases, certificates, and certificate chains.
  2. DigiCert: What Are SSL, TLS, and HTTPS?
  3. DigiCert: What Is an SSL Certificate?

Share this post:

Continue this series

Understanding HTTPS / TLS / SSL

  1. Understanding HTTPS, TLS, and SSL (Part 1): Core Concepts and Local Self-Signed CertificatesYou are here
  2. Understanding HTTPS, TLS, and SSL (Part 2): Visualizing the TLS Handshake and Decrypting Traffic

Comments

Questions, corrections, and experiences are welcome. Sign in with GitHub to comment; both language versions share this discussion.

Comments are available on the live site only.