TLS1.3 Data Communication b/w Client & Server using python sockets

This post is about , creating a TLS1.3 tunnels between client and server using python sockets.

This is a simple communication program. You can write the program based on the logic that you are looking for and create TLS1.3 Tunnels.

  1. Create self signed certificates for client and server.
  2. Openssl1.1 Version (It has support for TLS1.3 Tunnels)
  3. Write python client and server socket program.
  4. Client Sends data to the Server , In this example server is waiting at the port (4443)
    1. Client sends the Message Client –> Hi, Praneeth Here …
  5. Server replies back to the client with the below message.
    1. Server –> Hi Praneeth, How are you doing ?
Figure 1 : Simple communication b/w Client and Server for TLS1.3 Tunnels, Data is being sent in TLS1.3 Tunnels

Client and Server Socket Program

Below program is the client socket Sending data to the server waiting at the port “4443”. We are using loop back address here as we are running client and server in same machine. We can run the same program in multiple servers as well. Name the client socket program as client.py.

Client will send the message “Client –> Hi, Praneeth Here …” to the Server.

import socket
import ssl
import sslkeylog
import os

pemServer = "ca.pem"
keyClient = "client.key"
pemClient = "client.pem"

sslkeylog.set_keylog('SSLKEYLOGFILE')

########
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.options |= (
        ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
    )

context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(pemServer)
context.load_cert_chain(certfile=pemClient, keyfile=keyClient)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client = context.wrap_socket(client)
client.connect(("127.0.0.1", 4443))

print(sslkeylog.set_keylog(context))

client.send(bytes("Client --> Hi, Praneeth Here ...\n", encoding='utf8'))

from_server = str(client.recv(4096),encoding='utf8')
print(from_server)

client.close()

The below program is the server program, server is waiting at the port 4443. Once it receives the message it will send the reply to the client “Server –> Hi Praneeth, How are you doing ?“.

Name the below server program as server.py.

import socket
import ssl


pemServer = "ca.pem"
keyClient = "server.key"
pemClient = "server.pem"

context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.options |= (
        ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
    )

context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(pemServer)
context.load_cert_chain(certfile=pemClient, keyfile=keyClient)

serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

serv = context.wrap_socket(serv)

serv.bind(("127.0.0.1", 4443))
serv.listen(5)

while True:
    conn, addr = serv.accept()
    from_client = ''

    while True:
        data = str(conn.recv(4096), encoding='utf8') # The received data type is byte, converted to str
        if not data:
            break
        from_client = from_client + data
        print(from_client)

        conn.send(bytes("Server --> Hi Praneeth, How are you doing ?\n",encoding='utf8')) # Convert str to byte type, you need to use byte when transmitting

    conn.close()

Now first run the server program as python3.8 server.py, and observe the below screen shot.

Figure 2 : Server is Waiting to receive the data

Now run the client program as python3.8 client.py, and observe the below output on server and client.

Figure 3 : Server Received the Data “Hi, Praneeth Here …”
Figure 4 : Client Received the data “Server –> Hi Praneeth, How are you doing ?” from server

Observe the below capture when this communication happened b/w client and server.

We can observe that TLS1.3 handshake has happened between client and server and also observe that data is being sent in TLS1.3 tunnels b/w client and server and the data is encrypted. I have captured data on loop back address as I am running client and server programs on loopback address.

Figure 5 : Communication b/w client and server , Observe that data is encrypted in packet no 10 and 12. This data is being sent in TLS1.3 Tunnels

Verify the Data with Wireshark

Now, Decrypt the TLS1.3 tunnels in wireshark and check the data that is being sent in the tunnels, for packet no 10 and 13, we will observe the below results.

Decrypted data on Packet no 10 (Traffic That is being sent from Client –> Server).

Figure 6 : Decrypted TLS1.3 Data that is being sent from Client to server (Observe the Decrypted Data for packet no 10)

Decrypted Data on packet no 13 (Traffic that is being sent from Server –> Client)

Figure 7 : Decrypted TLS1.3 Data that is being sent from server to client (packet no 13)

This is a very simple communication between client and server. We can write the logic based on the requirement.

This is all about creating communicating between client and server using TLS1.3 tunnels. In the next post we will learn about TLS1.3 tunnels decryption using wireshark.