Python ssl Module

The ssl module in Python provides a way to create secure network connections using the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It allows you to wrap existing socket objects and provides both client and server-side SSL functionality.

Table of Contents

  1. Introduction
  2. Key Classes and Functions
    • SSLContext
    • wrap_socket
    • create_default_context
    • SSLSocket
    • SSLObject
  3. Examples
    • Creating a Secure Client
    • Creating a Secure Server
    • Using Custom SSL Context
    • Verifying Certificates
    • Using Non-Blocking Sockets
  4. Real-World Use Case
  5. Conclusion
  6. References

Introduction

The ssl module is essential for creating secure connections in network applications. It provides tools to wrap sockets with SSL/TLS support, ensuring that data transmitted over the network is encrypted and secure.

Key Classes and Functions

SSLContext

An SSLContext object holds various SSL-related settings and configurations. It is used to create SSL-wrapped sockets.

import ssl

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

wrap_socket

Wraps an existing socket in an SSL context, providing SSL/TLS functionality.

wrapped_socket = context.wrap_socket(socket.socket(), server_hostname='example.com')

create_default_context

Creates an SSLContext object with default settings.

context = ssl.create_default_context()

SSLSocket

An SSLSocket object represents an SSL-wrapped socket.

SSLObject

An SSLObject represents a non-networked SSL protocol instance.

Examples

Creating a Secure Client

import socket
import ssl

def secure_client():
    context = ssl.create_default_context()

    with socket.create_connection(('www.example.com', 443)) as sock:
        with context.wrap_socket(sock, server_hostname='www.example.com') as ssock:
            ssock.sendall(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
            print(ssock.recv(4096).decode())

if __name__ == '__main__':
    secure_client()

Creating a Secure Server

import socket
import ssl

def secure_server():
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.load_cert_chain(certfile='cert.pem', keyfile='key.pem')

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
        sock.bind(('localhost', 8443))
        sock.listen(5)
        with context.wrap_socket(sock, server_side=True) as ssock:
            conn, addr = ssock.accept()
            print(f'Connection from {addr}')
            data = conn.recv(1024)
            conn.sendall(b'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, World!')
            conn.close()

if __name__ == '__main__':
    secure_server()

Using Custom SSL Context

import socket
import ssl

def secure_client_with_custom_context():
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    context.verify_mode = ssl.CERT_REQUIRED
    context.check_hostname = True
    context.load_default_certs()

    with socket.create_connection(('www.example.com', 443)) as sock:
        with context.wrap_socket(sock, server_hostname='www.example.com') as ssock:
            ssock.sendall(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
            print(ssock.recv(4096).decode())

if __name__ == '__main__':
    secure_client_with_custom_context()

Verifying Certificates

import socket
import ssl

def secure_client_verify_cert():
    context = ssl.create_default_context()
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_verify_locations('path/to/cafile.pem')

    with socket.create_connection(('www.example.com', 443)) as sock:
        with context.wrap_socket(sock, server_hostname='www.example.com') as ssock:
            ssock.sendall(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
            print(ssock.recv(4096).decode())

if __name__ == '__main__':
    secure_client_verify_cert()

Using Non-Blocking Sockets

import socket
import ssl
import select

def non_blocking_secure_client():
    context = ssl.create_default_context()

    with socket.create_connection(('www.example.com', 443)) as sock:
        with context.wrap_socket(sock, server_hostname='www.example.com', do_handshake_on_connect=False) as ssock:
            ssock.setblocking(0)
            while True:
                try:
                    ssock.do_handshake()
                    break
                except ssl.SSLWantReadError:
                    select.select([ssock], [], [])
                except ssl.SSLWantWriteError:
                    select.select([], [ssock], [])
            
            ssock.sendall(b'GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n')
            print(ssock.recv(4096).decode())

if __name__ == '__main__':
    non_blocking_secure_client()

Real-World Use Case

Secure File Transfer

import socket
import ssl

def secure_file_transfer_client(file_path):
    context = ssl.create_default_context()

    with socket.create_connection(('localhost', 8443)) as sock:
        with context.wrap_socket(sock, server_hostname='localhost') as ssock:
            with open(file_path, 'rb') as f:
                data = f.read()
                ssock.sendall(data)

def secure_file_transfer_server(save_path):
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.load_cert_chain(certfile='cert.pem', keyfile='key.pem')

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
        sock.bind(('localhost', 8443))
        sock.listen(5)
        with context.wrap_socket(sock, server_side=True) as ssock:
            conn, addr = ssock.accept()
            print(f'Connection from {addr}')
            data = conn.recv(4096)
            with open(save_path, 'wb') as f:
                f.write(data)
            conn.close()

if __name__ == '__main__':
    # Run the server in one terminal
    # secure_file_transfer_server('received_file.txt')
    
    # Run the client in another terminal
    # secure_file_transfer_client('file_to_send.txt')
    pass

Conclusion

The ssl module in Python is essential for creating secure network connections. It provides a comprehensive set of tools for SSL/TLS support, including creating SSL contexts, wrapping sockets, and verifying certificates. This module ensures that your data is encrypted and secure during transmission over the network.

References

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare