In today’s data-driven world, transferring files securely between machines is a common but critical task. Whether you’re syncing backup files, sharing sensitive documents, or building a peer-to-peer system, data security and integrity are paramount. In this tutorial, we’ll walk you through how to build a Secure File Transfer Application in Python using sockets and add TLS encryption to keep your data safe during transit.
Why Secure File Transfer?
Transferring files over a network without encryption exposes them to risks like:
- Packet sniffing and data interception
- Man-in-the-middle (MITM) attacks
- Data tampering and corruption
By securing file transfers using TLS (Transport Layer Security) over Python sockets, we ensure:
- Encryption of transmitted data
- Authentication of parties (via certificates)
- Data integrity verification
Prerequisites
Make sure you have the following:
- Python 3.x installed
- Basic understanding of sockets and file handling
- openssl installed (for generating certificates)
Project Structure
secure_file_transfer/ ├── server.py ├── client.py ├── example.txt ├── certs/ │ ├── server.crt │ ├── server.key
The steps involved in the program are as follows:
- Generate TLS Certificates
- Build the Secure Server
- Build the Secure Client
- Test Your Secure File Transfer
ALSO READ:
Overall Program
The client and sever will do the following:
- Server: Listens on a secure (TLS-wrapped) socket, accepts a connection, receives the filename and file size, then reads and saves the incoming file data.
- Client: Connects to the server using TLS, sends the filename and size, then reads the file in chunks and securely sends it to the server.
Generate TLS Certificates
To enable encryption, generate a self-signed SSL certificate:
mkdir certs
openssl req -newkey rsa:2048 -nodes -keyout certs/server.key -x509 -days 365 -out certs/server.crt
You’ll be prompted to enter some details (e.g., Country, State). These are used in the certificate metadata.
Build the Secure Server
Create a file called server.py:
import socket
import ssl
import os
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 5001
BUFFER_SIZE = 4096
CERT_FILE = 'certs/server.crt'
KEY_FILE = 'certs/server.key'
def start_secure_server():
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)
# Create TCP socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
sock.bind((SERVER_HOST, SERVER_PORT))
sock.listen(5)
print(f"[*] Listening on {SERVER_HOST}:{SERVER_PORT}...")
# Wrap socket with TLS
with context.wrap_socket(sock, server_side=True) as ssock:
conn, addr = ssock.accept()
print(f"[+] Connection from {addr}")
# Receive file info
filename = conn.recv(BUFFER_SIZE).decode()
conn.send(b'OK') # Acknowledge
filesize = int(conn.recv(BUFFER_SIZE).decode())
conn.send(b'OK')
with open(f"received_{filename}", 'wb') as f:
received = 0
while received < filesize:
data = conn.recv(BUFFER_SIZE)
if not data:
break
f.write(data)
received += len(data)
print(f"[✓] File '{filename}' received successfully!")
if __name__ == '__main__':
start_secure_server()
Build the Secure Client
Create a file called client.py:
import socket
import ssl
import os
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 5001
BUFFER_SIZE = 4096
FILENAME = 'example.txt' # Replace with your file
def send_secure_file():
context = ssl.create_default_context()
# Create socket and wrap it with SSL
with socket.create_connection((SERVER_HOST, SERVER_PORT)) as sock:
with context.wrap_socket(sock, server_hostname=SERVER_HOST) as ssock:
print(f"[+] Connected to {SERVER_HOST}:{SERVER_PORT}")
# Send file name and wait for ack
ssock.send(FILENAME.encode())
ssock.recv(BUFFER_SIZE)
# Send file size and wait for ack
filesize = os.path.getsize(FILENAME)
ssock.send(str(filesize).encode())
ssock.recv(BUFFER_SIZE)
# Send file content
with open(FILENAME, 'rb') as f:
while True:
bytes_read = f.read(BUFFER_SIZE)
if not bytes_read:
break
ssock.sendall(bytes_read)
print(f"[✓] File '{FILENAME}' sent successfully!")
if __name__ == '__main__':
send_secure_file()
Test Your Secure File Transfer
Run the server in one terminal:
python3 server.py
Run the client in another terminal:
python3 client.py
Check that received_example.txt is created on the server with the same contents.
Security Tips
- Always verify certificates in production using certificate authorities (CA)
- Use mutual TLS (mTLS) for client authentication
- Add retry mechanisms and file hash checks (like SHA-256) for integrity
- Use threading on the server to handle multiple clients concurrently
Conclusion
Building a secure file transfer application using Python sockets is both educational and practical. With a few lines of code and the power of the ssl module, you can easily integrate TLS to encrypt communications, ensuring your files are transferred securely and reliably.