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
- Introduction
- Key Classes and Functions
SSLContext
wrap_socket
create_default_context
SSLSocket
SSLObject
- Examples
- Creating a Secure Client
- Creating a Secure Server
- Using Custom SSL Context
- Verifying Certificates
- Using Non-Blocking Sockets
- Real-World Use Case
- Conclusion
- 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.
Comments
Post a Comment
Leave Comment