MTLS-Everything You need to know (Part-I)

Sachin Kumar Shukla
8 min readMar 25, 2023

--

For Accessing the Backend Service from Amazon API Gateway using MTLS, refer Part-II https://medium.com/@skshukla.0336/mtls-aws-api-gateway-part-ii-15d338385c65

1. Introduction

This article describes how Client and Server can communicate securely with each other over Transport Layer Security (TLS).

The concepts being covered here are,

  • One-Way TLS Authentication
  • Two-Way TLS Authentication

2. Terminology

Before going for the theory and demo, let’s understand some of the concepts and terminologies around Secure Communications in general.

2.1 Certificate Request

A Client or Server in order to acquire a valid certificate first need to create a CSR (Certificate Request) file which they need to submit to the Certificate Authority which can sign and issue a valid certificate

2.2 Certificate Authority

A Certificate Authority is a trusted organization who confirm the authenticity of a website (Server). Their primarily responsibilities are,

  • Issue the Certificates to the Entities (Servers, Clients, Websites)
  • Confirm whether it’s the same Website which it claims it is.

Few of the Certificate Authorities are VeriSign, DigiCert.

2.3 Certificate

A (public) certificate is what is issued to the Entity (Server, or Client). As CA issues the certificates they can confirm also whether it’s a valid certificate signed by them or not.

2.3 SSL vs TLS

SSL, Stands for, Server Socket Layer however TLS, Stand for, Transport Layer Security. SSL is just the older name.

2.4 Public/Private keys

  • Public Key is used to Encrypt the data. (Think of certificates. No harm passing the public key, certificate, to anyone publicly)
  • Private Key is used to Decrypt the data, encrypted by Public key.
  • Private Key is like a password which should never cross the boundry of a system who has generated it. Consider it very secure. Think of it a system password which you don’t even share with your manager or any other person in authority.

3. One-Way Authentication

To understand MTLS better, lets start first with the one-way authentication. Clients and Servers can be geographically apart, as they are programs, machines/robots and hence they need to confirm the other side’s identity they are communicating with in an automated manner.

One-Way Transport Layer Security
1.0 One Way Transport Layer Security (TLS)
  1. Server generates the private key and CSR. The CSR is just a request which needs to be traded for the valid certificate. Only CAs can issue the certificates.
  2. CSR is presented to the CA.
  3. CAs may verify the identity of Website (Server), which sometime may include a physical visit by them to the business premises in case of enterprise, and issue the public certificate. (Till this point it’s a one time setup)
  4. Client requests the server and the HandShake process starts.
  5. Server in tern returns its Certificate (public key) to the client.
  6. Client (a program, browsers) can confirm the CAs whether it’s a valid certificate issued by them or not. This step is where Client is assured whether the party with which Client is talking is the same which it claims it is. (Client has verified the identity of Server)
  7. If all looks good, Communication starts (I am skipping the further handshake process as the focus is on setup and MTLS)

3. Two-Way Authentication

In Two-way authentication both the Server and Client needs to validate their identity in terms of communication to happen. The way it differs from above case is when server gets the request and it does not identify the client then it would reject the request.

  1. Server generates the private key and CSR as above
  2. CSR is presented to the CA.
  3. (a) CAs may verify the identity of Website (Server) and issue the public certificate. (b) Server would import the public certificate or CA (root cert) to its Trust Store that way any client who is issued a cert by “this Authority“ can communicate with the Server.
  4. Client requests the server and the HandShake process starts.
  5. Server in tern returns its Certificate (public key) to the client.
  6. Client (a program, browsers) can confirm the CAs whether it’s a valid certificate issued by them or not. This step is where Client is assured whether the party with which Client is talking is the same which it claims it is.
  7. While making a call to the server, Client uses its Certificate and Client Key for the communication which is validated at the Server side to ensure the identity of client. Server consults Trust Store whether it’s a valid client to be given access or not. Please note, Client Key does not travel over network, it’s a private key and used to decrypt the data over the TCP tunnel.

3. Commands

For this demo, let’s work with Self Signed Certificate. It’s easier to generate and work with Self Signed Certificate. The only problem is if accessing via browser it would complain as it does not recognise the certs. They are equally secure as the one generated by the CAs.

# OpenSSL version being used is "OpenSSL 3.1.0" (Older version gave some issues)
# All password used here is 12345678 for simplicity

# Generating Root Cert

openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 \
-keyout rootCA.key -out rootCA.crt -passout pass:12345678

# Generating Server key and CSR

openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr \
-passout pass:12345678

# Content of Server EXT file (server.ext)

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = api-server.skshukla.com

# Recall Step-3, CA would take CSR, use it's key and password
# and issue Certificate

openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in server.csr \
-out server.crt -days 365 -CAcreateserial -extfile server.ext \
-passin pass:12345678

# Generate p12 file (Contains the key and cert)

openssl pkcs12 -export -out server.p12 -name "api-server.skshukla.com" \
-inkey server.key -in server.crt -passin pass:12345678 \
-password pass:12345678

# Create KeyStore

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 \
-destkeystore myserver_keystore.jks -deststoretype JKS

# For One Way TLS communication, Steps till generating KeyStore is sufficient.

# Generate Trust Store

keytool -import -trustcacerts -noprompt -alias ca \
-ext san=dns:${SERVER_CN},ip:127.0.0.1 -file rootCA.crt \
-keystore myserver_truststore.jks

# So far, Server setup is fully done. Now for any client to communicate
# to the server, we need to generate the "CLIENT" certs and get it signed
# by the same Authority whose cert is stored in Trust Store.

# Client generates it's key and CSR

openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr \
-passout pass:12345678

# CA use it's key and credentials along with the CSR and issue Cert

openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in client.csr \
-out client.crt -days 365 -CAcreateserial -passin pass:12345678

openssl pkcs12 -export -out client.p12 -name "client" -inkey client.key \
-in client.crt -passin pass:12345678 -password pass:12345678

4a. Make it work for One-Way TLS Authentication

  • Clone the Spring Boot Sample application.
# My current working directory is: /Users/sachin/tmp/t2

git clone https://github.com/skshukla/tlsdemo.git
  • Refer the script at script in github, the only variable to change there is (PROJ_DIR) and give the path for the project checked out. e.g. in my case. (If needed, change the Common names too, but not mandatory for the demo to work)
PROJ_DIR=/Users/sachin/tmp/t2/tlsdemo
  • Copy the whole content of scripts.sh file (after adjusting the above variable) and paste it to terminal and press enter. If all goes good, it would print the last few lines as below.

By this time, work/cert directory would be created and it would contain all the certificates.

The script would also copy the final keystore and trust store files to the src/main/resources folder

  • Start the application by issuing the command
mvn clean spring-boot:run
  • As the certificate has been generated (in this demo) using api-server.skshukla.com as the COMMON NAME for server and hence access the application using this endpoint. Make entry in hostfile to point this name to your localhost.
  • Once the application is up and host entry is made, access the application by using the curl command.

# Below command would result into error, as now client
# needs to verify the identity of server

curl -X GET \
https://api-server.skshukla.com:8443

# Use unsecure option (-k), this would tell that client risks to access the server
# as it does not identify it.

curl -k -X GET \
https://api-server.skshukla.com:8443

# Finally, to access the application use the root cert file,
# this tells that client would trust the server only if
# it's trusted by this Authority. (Note, -k, option is not given)

curl -X GET \
--cacert /Users/sachin/tmp/t2/tlsdemo/work/certs/rootCA.crt \
https://api-server.skshukla.com:8443

4b. Make it work for Two-Way TLS Authentication

The good news is, if you have followed the steps so far, you would have to modify only one config under “src/main/resources/application.yaml

As the TrustStore is also copied to resources folder and hence application would trust those client who have been verified by the same CA, All that is needed to uncomment the line below and bring up the application again.

client-auth: need
  • now the above command would fail as this time Server does not identify the client and rejects the request.
  • To make it work use the curl command with right client details (key, crt, root cert and password). Please note, — cacert is only needed in case of Self Signed Certificate, as curl needs to know that it’s the right server its going to access based on this certificate which client trusts. In case of certs issued by the actual CAs, this option can be ommitted.
curl -X GET --pass 12345678 \
--key /Users/sachin/tmp/t2/tlsdemo/work/certs/client.key \
--cert /Users/sachin/tmp/t2/tlsdemo/work/certs/client.crt \
--cacert /Users/sachin/tmp/t2/tlsdemo/work/certs/rootCA.crt \
https://api-server.skshukla.com:8443

5. Conclusion

We learned how to implement One-Way and Two-Way Authentication over Transport Layer Security and securing the Backend Service which improves the security of the system. To know how to implement the same in Cloud using Amazon API Gateway, visit the Part-II https://medium.com/@skshukla.0336/mtls-aws-api-gateway-part-ii-15d338385c65

Linkedin:

https://www.linkedin.com/in/sks336/

YouTube:

https://www.youtube.com/channel/UCHkwNRHcXizsBiPE0smkJAA

--

--