HTTPS, SSL and TLS Explained

You’ve probably heard of these protocols that protect our data when we browse the web. In this post, we’ll delve into the world of HTTPS and TLS, exploring how they work, why they’re important, and how you can ensure your servers stay secure in the digital age.

Let’s cut it short, SSL (Secure Sockets Layer), was the predecessor to TLS (Transport Layer Security) and was developed by Netscape in the mid-1990s. So SSL is deprecated (exists but not recommended/supported) and TLS is currently used, more precisely TLS 1.3, defined in August 2018. Of course HTTPS is just HTTP over TLS.

Too short? OKe, maybe this was a bit too fast. For those who want to know a little more. We’re back to square one.

The history

While SSL served as a foundational technology for securing online communication, it had several vulnerabilities that made it susceptible to attacks. In response to these weaknesses, the Internet Engineering Task Force (IETF) developed TLS as an improved and more secure version of SSL. TLS builds upon the principles of SSL but includes enhancements to address security flaws and improve overall performance.

So if someone mentions SSL, he means TLS. You can say it’s TLS now and ask him if he’s been living under a rock for the last decades. That’s why in the following text I will only use the term TLS.

TLS operates at the transport layer of the OSI model and uses a combination of symmetric and asymmetric encryption algorithms to secure data transmission. TLS certificates, issued by trusted Certificate Authorities (CAs), are used to authenticate the identity of websites and ensure the integrity of the encrypted communication. When a client connects to a server over HTTPS, the TLS handshake process begins, during which the two parties negotiate encryption parameters and exchange cryptographic keys. Once the secure connection is established, data can be transmitted securely between the client and server.

HTTP vs HTTPS

HTTP (Hypertext Transfer Protocol) and HTTPS (HTTP Secure) are both protocols used for transferring data over the internet, but they differ in terms of security and encryption. HTTP transmits data in plain text, which means that the data is not encrypted and can be intercepted and read by unauthorized parties.

HTTPS uses TLS to encrypt data transmitted between a client and a web server. Using HTTPS is essential for securing sensitive information and ensuring secure communication between clients and servers on the web.

In this illustrative example, the client is a PC that connects to a social media server, that is, a user uses a browser to log into their social media account. In doing so, certain sensitive data is sent, such as a password. Using a tool like Wireshark, this data would be easy to intercept if HTTPS is not used.

What is needed for TLS?

In a typical TLS connection, the server presents its certificate to the client to establish trust, and the client and server negotiate a shared encryption key to secure the communication. So, to begin with, we need:

  1. a Server Key Store that stores
    • the Server’s Private Key and
    • the Server’s TLS Certificate
      and
  2. a Trust Store that stores
    • root certificates of trusted CAs

Now we have come to concepts and things that are already PKI and I don’t want to go too far into the meaning of things like Certificate Authorities (CAs), Root CAs and Root certificates. Perhaps in some future post.

Trust Store and Key Store

A trust store and a key store are both types of storage facilities for cryptographic keys and certificates in a secure manner, but they serve different purposes. A trust store is used to store trusted certificates for verifying the identity of parties involved in a communication, while a key store is used to store cryptographic keys and certificates for encryption and authentication purposes.

Java’s (Secret) Trust Store

Using a tool I can recommend, the KeyStore Explorer, it is possible to open trust store and key store files. The simplest example would be Java’s trust store, which is usually under %JAVA_HOME%/lib/security/cacerts. In newer versions of Java, this file is not password protected, while in older versions (e.g. Java 11) the password is changeit.

Every time your Java application tries to establish a connection to a URL that starts with https, it will receive a certificate from the server. If there is no certificate from its issuer in this cacerts file and assuming you have not changed the TLS parameters, it will refuse to connect (SSLHandshakeException). More on this later.

My Server’s Key Store

This is what a server’s key store looks like. One RSA 2048 key with the appropriate certificate and everything protected by a password. Here we come to the previously mentioned “in a secure manner”. Unlike Java’s new trust store, these files are usually password protected.

For someone who encounters this for the first time, it can be said that it is similar to a password-protected RAR/ZIP file in which there are some (keys and certificate) files. You will usually get files like this from your PKI expert, it is possible to buy them as well as to create them yourself (e.g. using XCA). Since the point of this post is not “How to issue TLS certificates”, I’ll just mention that there are different formats, the two most popular of which are JKS and P12.

JKS vs P12

Java Key Store [.jks] is specific to Java and is commonly used in Java applications, while PKCS#12 [.p12/.pfx] is a standard format that offers portability and interoperability across different platforms. Since P12 has been around long enough to be supported almost everywhere, my recommendation is to use the P12 format instead of JKS. After all, it’s always possible to open the file using KeyStore Explorer and save it as another format if necessary. For the more experienced, it is possible to do the same with OpenSSL commands.

TLS vs mTLS (Mutual TLS)

While TLS provides encryption and security for communication between a client and a server, mTLS enhances security by adding mutual authentication, ensuring that both parties are who they claim to be. 

TLS secures communication between a client and a server by encrypting data and authenticating the server. Basically anyone who trusts this server can connect to it. By trusting the server, I mean trusting its certificate. More precisely, that the server certificate was issued by a CA that we have in our trust store.

mTLS extends TLS by adding mutual authentication, where both the client and the server authenticate each other using digital certificates. In a typical TLS connection, only the server presents a certificate to prove its identity. With mTLS, both the client and the server exchange certificates, verifying each other’s identities before establishing a secure connection. Only those whom the server trusts can connect to such a server.

Simply put, in the case of mTLS, if you are not in the guest list (trust store) of the server, you cannot enter (open the website).

Real life example:
Let’s implement HTTPS on a Server

Using an Open Source PKI, I created my own CA called DraganCA. With that CA I generated two TLS key stores, a server key store (keystore.p12) and a client key store (SuperDragan.p12). And not to forget, I need the certificate from the CA itself (DraganCA.cer) so that I can add it to the trust stores.

If you want to try this yourself, the mentioned files are added below and the password for the key stores is: Fooo1234. Now we can begin.

The Server

With so many application servers to choose from, I decided to go with Tomcat, purely because of the 13,8 MB size.

  1. Download the apache-tomcat-10.1.25-windows-x64.zip from tomcat.apache.org/download
  2. Unzip (e.g. to C:\Servers\apache-tomcat-10.1.25\)
  3. Run \bin\startup.bat
  4. The Tomcat console will pop up, type http://127.0.0.1:8080/ in the browser to see if the server is running.

Adding HTTPS

  1. Stop the server by closing the Tomcat console
  2. Copy the server key store to \conf\keystore.p12
  3. Edit \conf\server.xml
<Service name="Catalina">
...
<Connector port="80" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="443"
           maxParameterCount="1000" />

<!-- HTTPS (TLS) Connector on port 443 -->
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           SSLEnabled="true" scheme="https" secure="true"
           maxParameterCount="1000" maxThreads="250" >
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
    <SSLHostConfig sslProtocol="TLSv1.3" >
        <Certificate certificateKeystoreFile="conf/keystore.p12"
                     certificateKeystorePassword="Fooo1234"
                     certificateKeystoreType="PKCS12" 
                     type="RSA" />
    </SSLHostConfig>
</Connector>
...
</Service>
  1. Start the server again with \bin\startup.bat
  2. In the browser, open https://localhost/ or https://127.0.0.1/

Oh no, we messed something up. Did we?

Everything is fine, the problem is that our browser does not recognize DraganCA as the well-known Root CA. Of course, we can click “Advanced…” and accept the risk, but we won’t do that. That way, there will always be a security warning, which is annoying. So…

  1. Open Internet Options from the Control Panel or via search
  2. In the Content tab, click on Certificates
  3. Find the Trusted Root Certification Authorities tab and import the DraganCA.crt there
  1. Restart the Browser
  2. Go to https://localhost/ or https://127.0.0.1/

Congrats, you just implemented HTTPS on your Tomcat server.

mTLS Server Configuration

To implement mTLS, you need to add a trust store on the server side, that is, configure the connector accordingly.

<Service name="Catalina">
...
<!-- Mutual TLS (mTLS) Connector  -->
<Connector port="443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
   scheme="https" secure="true" SSLEnabled="true"
   maxParameterCount="1000" maxThreads="250" >
      <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
      <SSLHostConfig sslProtocol="TLSv1.3"
	      truststoreFile="conf/truststore.p12"
	      truststorePassword="Fooo1234"
	      truststoreType="PKCS12" 
	      certificateVerification="required" >
	      <Certificate certificateKeystoreFile="conf/keystore.p12"
		      certificateKeystorePassword="Fooo1234"
		      certificateKeystoreType="PKCS12"
		      type="RSA" />
      </SSLHostConfig>
</Connector>
...
</Service>

A very important parameter is certificateVerification="required", which connects only clients that have a certificate issued by a trusted CA. As DraganCA is in the server’s trust store (truststoreFile="conf/truststore.p12"), this server will allow all clients (with the appropriate client certificate) issued by DraganCA to connect to it. It’s good that we have one (SuperDragan.p12). That’s it, the server configured like this can only be accessed by those to whom we issue a client certificate.

mTLS Client Configuration

So we need to import SuperDragan.p12 into a browser or the application that will connect to our server. If we don’t do that and try to access the server, we will get the following error.

mTLS with Firefox as the Client

The import of the client certificate depends on the browser, in the case of Firefox, we do it in the settings of the browser.

If we try to open the Tomcat home page after importing the certificate, we must first select the certificate before we can access the page.

mTLS with a Java Application as the Client

Of course, this also applies to client applications that use our server, in case of Java applications, the following parameters must be added in order to use the client certificate when establishing a connection.

-Djavax.net.ssl.trustStore=D:/TLS/truststore.p12
-Djavax.net.ssl.trustStorePassword=Fooo1234
-Djavax.net.ssl.trustStoreType=PKCS12
-Djavax.net.ssl.keyStore=D:/TLS/client_keystore.p12
-Djavax.net.ssl.keyStorePassword=Fooo1234
-Djavax.net.ssl.keyStoreType=PKCS12
-Dhttps.protocols=TLSv1.3

How to stay up to date

Don’t worry, it’ll be on the news. It’s only a matter of time before TLS 1.2 is declared deprecated. If you just regularly upgrade your browser, you will quickly notice these changes.

Disclaimer

OpenAI’s gpt-3.5-turbo was used to create parts of this post. freepik.com and storyset.com were used to generate some of the images.

2 thoughts on “HTTPS, SSL and TLS Explained

  1. Avatar
    hgn says:

    Can one keystore be used as a server keystore as well as a clinet keystore, where it uses the same key when communicating as a server but also when connecting to other servers as a client?

    Reply
    1. admin
      admin says:

      It depends on the certificate for that key. It’s possible, although in the certificate under “Extensions” it says either “TLS Web Server Authentication” for the server or “TLS Web Client Authentication” if it is a client. If both extensions are present, it’s possible. If not, you usually get a “Bad Certificate” error.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *