How to Configure SSL in Aiohttp with OpenSSL
In this tutorial, you’ll learn how to configure SSL in Aiohttp using OpenSSL.
You’ll create self-signed certificates, set up SSL contexts, and implement secure connections for both servers and clients.
Create Self-signed Certificate using OpenSSL
Generate Private Key
To generate a private key, you can use the following OpenSSL command:
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
This command generates a 2048-bit RSA private key and saves it to the file private_key.pem
.
Create Certificate Signing Request (CSR)
Next, create a certificate signing request using the generated private key:
openssl req -new -key private_key.pem -out csr.pem
Output:
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:California Locality Name (eg, city) []:San Francisco Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Corp Organizational Unit Name (eg, section) []:IT Department Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []:admin@local Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
This interactive process creates a CSR file named csr.pem
.
Self-sign the Certificate
To self-sign the certificate using the CSR and private key, use this command:
openssl x509 -req -days 365 -in csr.pem -signkey private_key.pem -out certificate.pem
Output:
Signature ok subject=C = US, ST = California, L = San Francisco, O = Example Corp, OU = IT Department, CN = localhost, emailAddress = admin@local Getting Private key
This command generates a self-signed certificate valid for 365 days and saves it as certificate.pem
.
Configure SSL context
To create an SSL context object in Python, use the following code:
import ssl ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
This creates a default SSL context for client authentication.
Load Certificate and Private key
Load the certificate and private key into the SSL context:
ssl_context.load_cert_chain(certfile='certificate.pem', keyfile='private_key.pem')
This code loads the certificate and private key files into the SSL context.
Set SSL protocols and ciphers
To set specific SSL protocols and ciphers, use the following code:
ssl_context.set_ciphers('ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256') ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
This code sets the cipher suite to use ECDHE-RSA with AES256 or AES128 in GCM mode, and uses TLS version 1.2 for improved security.
Implement SSL in Aiohttp Server
To configure an Aiohttp server to use SSL, modify your server setup code:
from aiohttp import web async def hello(request): return web.Response(text="Hello, secure world!") app = web.Application() app.add_routes([web.get('/', hello)]) web.run_app(app, ssl_context=ssl_context)
When you visit https://127.0.0.1:8443
and accept the warning you’ll see Hello world message.
Client-side SSL configuration
To create an SSL-enabled client session in Aiohttp, use the following code:
import aiohttp import ssl import asyncio async def fetch(): ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ssl_context.load_verify_locations('certificate.pem') async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=ssl_context)) as session: async with session.get('https://localhost:8443') as response: print(response.status) print(await response.text()) asyncio.run(fetch())
Output:
200 Hello, secure world!
This code creates a client session with SSL enabled and verifies the server certificate.
Handle SSL in WebSockets
To create a secure WebSocket server, modify your WebSocket handler:
from aiohttp import web import ssl async def websocket_handler(request): ws = web.WebSocketResponse() await ws.prepare(request) async for msg in ws: if msg.type == web.WSMsgType.TEXT: await ws.send_str(f"You said: {msg.data}") elif msg.type == web.WSMsgType.ERROR: print(f'WebSocket connection closed with exception {ws.exception()}') return ws app = web.Application() app.add_routes([web.get('/ws', websocket_handler)]) ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile='certificate.pem', keyfile='private_key.pem') web.run_app(app, ssl_context=ssl_context)
This code sets up a secure WebSocket server using the SSL context we created earlier.
Implement SSL for websocket clients
To create a secure WebSocket client, use the following code:
import asyncio import ssl import aiohttp async def main(): ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) ssl_context.load_verify_locations('certificate.pem') async with aiohttp.ClientSession() as session: async with session.ws_connect('wss://localhost:8443/ws', ssl=ssl_context) as ws: await ws.send_str("Hello, secure WebSocket!") async for msg in ws: if msg.type == aiohttp.WSMsgType.TEXT: print(f"Received: {msg.data}") elif msg.type == aiohttp.WSMsgType.CLOSED: break elif msg.type == aiohttp.WSMsgType.ERROR: break asyncio.run(main())
Output back from the server:
Received: You said: Hello, secure WebSocket!
This code creates a secure WebSocket client that connects to a WSS (WebSocket Secure) endpoint using the SSL context.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.