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.
- Create self signed certificates for client and server.
- Openssl1.1 Version (It has support for TLS1.3 Tunnels)
- Write python client and server socket program.
- Client Sends data to the Server , In this example server is waiting at the port (4443)
- Client sends the Message Client –> Hi, Praneeth Here …
- Server replies back to the client with the below message.
- Server –> Hi Praneeth, How are you doing ?

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.

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


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.

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).

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

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.