Mutual TLS
We all know the classic TLS that runs the web, but have you seen a client-provided TLS?
Published onUpdated on
4 min read
If you have tried working the web technology just a bit deeper than the surface-level React Tic Tac Toe projects, you might have come across the word TLS. TLS stands for “Transport Layer Security”, which refers to the encryption at level 4 in the OSI model. This is the key difference between HTTP and HTTPS.
We should work toward a universal linked information system, in which generality and portability are more important than fancy graphics techniques and complex extra facilities. The aim would be to allow a place to be found for any information or reference which one felt was important, and a way of finding it afterwards.
Well, sadly, with the state of the web right now, Tim has expressed concerns and disappointment.
If you just use the HyperText Protocol of HTTP, tranmission isn’t secure. Therefore, to put a secure layer ontop of HTTP, we created HTTPS, which now you know what the S stands for. Under HTTPS, transmission of HTTP can be secure, which can now contain sensitive information.
HTTPS leverages this by using TLS to transmit information, and in combination with that, it also requests the server to provide a certificate proving who they are instead of allowing any servers to send any data. If you ever see an error message that says something like “Connection isn’t secure”, it means that the server did not provide that certificate, and an HTTPS connection can not be established.
At the time of writing this, I am a final-year university student, probably graduating in the next 6 months if I don’t fail the graduate project (lol). As the final required course project, I chose to look into the Go programming language as a final send-off for the course “Advanced Web App Development”. Funnily, they actually opened two classes for this course on the same day of the week, but the second class is entirely focused on React, with little care to the backend side. Therefore, I switched myself to the other class to get myself familiar with more concepts that extend above and beyond just a React Web app.
This article was written for that class. This week’s theme is “To implement API security, research on methods to do so in the following 3 use cases”:
- Only internal machines can access (such as in an organization or an enterprise).
- A small number of clients can access.
- Anyone can access by registering.
I could think of that for the second situation, using an opaque API token would be the way, similar to how OpenAI or Gemini gives you that random jibberish key. For the third situation, I decided on a standard JWT. The first situation feels a bit tricky, but I asked around, consulted with some AIs, and got to mutual TLS.
Normally, a TLS certificate should be acquired from a trusted CA (or Certificate Authority). But just for a class demo, getting a CA to sign for us might be too crazy, and we can just use a self-signed certificate anyway. As long as the server trusts me as the Authority, then everything should work fine. I setup a script below to setup some certificate files that servers can use to present themselves.
#!/bin/sh
# Make sure to stop the script if any error happens.
set -e
# First, we need to create the root Authority.
# -nodes here tells OpenSSL to not use any password.
# Then we choose the Algorithm Type for the CA and make the root key.
openssl genrsa -out ./certs/ca.key 4096
openssl req -x509 -new -nodes -key ./certs/ca.key -sha256 -days 3650 -out ./certs/ca.crt \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=NNDK/CN=WNC Root CA"
# Then, for each client/server certificate, the process is similar.
# The difference should be on the Common Name field. We can differentiate
# between who and who using this, if our servers use mTLS.
openssl genrsa -out ./certs/server.key 2048
openssl req -new -key ./certs/server.key -out ./certs/server.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=NNDK/CN=Sakila"
openssl x509 -req -in ./certs/server.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/server.crt -days 365 -sha256
openssl genrsa -out ./certs/client1.key 2048
openssl req -new -key ./certs/client1.key -out ./certs/client1.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=App/CN=Client 1"
openssl x509 -req -in ./certs/client1.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/client1.crt -days 365 -sha256
openssl genrsa -out ./certs/client2.key 2048
openssl req -new -key ./certs/client2.key -out ./certs/client2.csr \
-subj "/C=VN/ST=HCMC/L=HCMC/O=WNC/OU=App/CN=Client 2"
openssl x509 -req -in ./certs/client2.csr -CA ./certs/ca.crt -CAkey ./certs/ca.key \
-CAcreateserial -out ./certs/client2.crt -days 365 -sha256