Client/server with SSLIntroduction[Back] We will now create our own SSL/TLS server and client in Python. First we need to generate a certificate for our server: openssl req -new -x509 -days 365 -nodes -out mycert.pem -keyout mycert.pem Next we will create a server which will listen on Port 443, and support two cipher suites ('AES256+ECDH:AES256+EDH'): import socket, ssl context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.load_cert_chain(certfile="mycert.pem") def handle(conn): conn.write(b'GET / HTTP/1.1\n') print(conn.recv().decode()) while True: sock = socket.socket() sock.bind(('', 443)) sock.listen(5) context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="mycert.pem") context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # optional context.set_ciphers('AES256+ECDH:AES256+EDH') while True: conn = None ssock, addr = sock.accept() try: conn = context.wrap_socket(ssock, server_side=True) handle(conn) except ssl.SSLError as e: print(e) finally: if conn: conn.close() Now we will create the client to connect on Port 443. As we have a self-signed certificate, we will disable the checking of the host and certificate (remember to change the IP address to the address of your local host): import socket, ssl HOST, PORT = '10.10.10.10', 443 def handle(conn): conn.write(b'GET / HTTP/1.1\n') print(conn.recv().decode()) def main(): sock = socket.socket(socket.AF_INET) context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) context.check_hostname = False context.verify_mode=ssl.CERT_NONE context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 conn = context.wrap_socket(sock, server_hostname=HOST) try: conn.connect((HOST, PORT)) handle(conn) finally: conn.close() if __name__ == '__main__': main() Now run Wireshark (sudo wireshark &), and capture from the Ethernet port. Now run the server, and then run the client. Stop Wireshark and determine: QuestionsThe cipher suites sent from server to the client (‘Server Hello’)? The cipher suite selected by the client (‘Client Hello’)? If we change the code to: context.set_ciphers(‘HIGH’) What are the cipher suites sent from server, and which cipher suite is selected by the client? A sample of the trace is [here]. Sample stringsKey exchange:
We can also use HIGH (256-bit); MEDIUM (128-bit); LOW (56-bit or 64-bit) |