Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
30 Jul 2025 · 5 min read ·Article 52 / 110
Go

52. TLS Mutual Authentication Between Client and Server

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

52. TLS Mutual Authentication Between Client and Server

In today’s era of cloud-native and Zero Trust Architecture, the need for secure digital communication has become increasingly vital. One of the most crucial mechanisms for securing communication between systems is TLS Mutual Authentication, often referred to as Mutual TLS (mTLS). This article explains the concept of mTLS along with a simple implementation between a client and server using Python, complete with a walkthrough of the flow and practical tips.


What Is TLS Mutual Authentication?

TLS (Transport Layer Security) is already very commonly used to ensure data security during the exchange of information between a client and a server. However, in most cases only the server needs to prove its authenticity to the client (server authentication), while the client does not need to prove its identity to the server.

With TLS Mutual Authentication, both parties—the client and the server—verify each other’s identity using digital certificates. This is especially important for service-to-service communication in modern environments such as Kubernetes, microservices, or APIs between organizations/enterprises.


TLS Mutual Authentication Flow Diagram

Let’s clarify the mutual TLS process with the following mermaid diagram:

MERMAID
sequenceDiagram
    participant Client
    participant Server
    participant CA

    Client->>CA: Meminta Sertifikat Client
    Server->>CA: Meminta Sertifikat Server
    Note over CA: CA menghasilkan dan menandatangani sertifikat
    Client->>Server: TLS handshake (mengirim sertifikat client)
    Server->>Client: TLS handshake (mengirim sertifikat server)
    Server->>CA: Verifikasi sertifikat dari client
    Client->>CA: Verifikasi sertifikat dari server
    Note over Client,Server: Jika verifikasi sukses, koneksi aman dibuka

Why Is mTLS Important?

  • Two-Way Authentication: Both parties must prove their identity to each other.
  • Higher Security: Reduces the risk of client/server impersonation.
  • Better Control: Only clients and servers that hold valid certificates are allowed to communicate with each other.

This practice is commonly used for internal APIs, communication between microservices, and when integrating with third-party vendors that require an ultra-secure channel.


Implementation Example: Python SSL mTLS

Now, let’s simulate mTLS in Python using the ssl and socket modules. But before writing the code, we first need to create the certificates.


1. Creating Certificates (Simulating a Simple CA)

We need 3 types of certificates:

  1. CA (Certificate Authority)
  2. Server Certificate (signed by the CA)
  3. Client Certificate (signed by the CA)

Steps Using OpenSSL (Linux/macOS)

Create a working folder, then run:

bash
 1# 1. Generate the CA's private key and certificate
 2openssl genrsa -out ca.key 4096
 3openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=ID/O=ExampleCA/CN=Example Root CA"
 4
 5# 2. Generate the Server's key and CSR (Certificate Signing Request)
 6openssl genrsa -out server.key 4096
 7openssl req -new -key server.key -out server.csr -subj "/C=ID/O=ExampleServer/CN=localhost"
 8
 9# 3. Sign the Server's certificate with the CA
10openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
11    -out server.crt -days 365
12
13# 4. Generate the Client's key and CSR
14openssl genrsa -out client.key 4096
15openssl req -new -key client.key -out client.csr -subj "/C=ID/O=ExampleClient/CN=client1"
16
17# 5. Sign the Client's certificate with the CA
18openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
19    -out client.crt -days 365

In the end, you will have:

FileDescription
ca.crtCA certificate (public)
ca.keyThe CA’s private key
server.crtServer certificate
server.keyServer private key
client.crtClient certificate
client.keyClient private key

2. Python Server Code with mTLS

python
 1import ssl, socket
 2
 3context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
 4context.load_cert_chain(certfile="server.crt", keyfile="server.key")
 5context.load_verify_locations(cafile="ca.crt")
 6context.verify_mode = ssl.CERT_REQUIRED  # Require a client certificate
 7
 8bindsocket = socket.socket()
 9bindsocket.bind(('localhost', 8443))
10bindsocket.listen(5)
11print("Server listening on port 8443...")
12
13while True:
14    newsocket, addr = bindsocket.accept()
15    with context.wrap_socket(newsocket, server_side=True) as ssock:
16        print(f"TLS connection from {addr}, client cert: {ssock.getpeercert()}")
17        data = ssock.recv(1024)
18        print("Received from client:", data.decode('utf-8'))
19        ssock.send(b'ACK from server')

3. Python Client Code with mTLS

python
 1import ssl, socket
 2
 3context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile="ca.crt")
 4context.load_cert_chain(certfile="client.crt", keyfile="client.key")
 5
 6with socket.create_connection(('localhost', 8443)) as sock:
 7    with context.wrap_socket(sock, server_hostname='localhost') as ssock:
 8        print("Connected. Server cert:", ssock.getpeercert())
 9        ssock.send(b'Hello from client!')
10        data = ssock.recv(1024)
11        print("Received:", data.decode('utf-8'))

4. Simulation and Testing

  1. Run the server: python server.py
  2. Run the client: python client.py

If you remove the client certificate on the client side, the server will reject the connection automatically.


TLS vs. mTLS Comparison Table

FeaturePlain TLSMutual TLS (mTLS)
Server AuthenticationYesYes
Client AuthenticationNoYes
Access KeyUsually password/APIDigital certificate/hard to forge
Common Use CaseHTTPS websiteInternal APIs, microservices, inter-org communication

Tips for Implementing mTLS in Production

  • Use a trusted CA (internal, HashiCorp Vault, or a PKI vendor).
  • Rotate/renew certificates periodically (automate this where possible).
  • Validate certificates (issuer and expiry) within your application code.
  • Use container secrets management to keep private keys secure.
  • Log handshake failures for auditing and troubleshooting.

Conclusion

mTLS is the gold standard for securing communication between digital services. In the finance, healthcare, and even cloud industries, mTLS reduces the attack surface from impersonation and MITM (Man-in-the-Middle) attacks. Infrastructure that adopts Zero Trust almost always implements mTLS.

To learn more, try this simulation locally, or integrate it into your DevOps stack (Istio, Envoy, Nginx). The better we understand the principles, the more mature the security posture of our applications/projects becomes.

Happy experimenting and stay secure!

Related Articles

💬 Comments