[파이썬] 자가 서명 인증서와 소켓 프로그래밍

In today’s digital world, security is of utmost importance. One such aspect of security is the use of self-signed certificates for securing communication over the internet. In this blog post, we’ll explore how to generate and use self-signed certificates in Python for socket programming.

What is a self-signed certificate?

A self-signed certificate is a digital certificate that is signed by the entity that created it rather than by a trusted certificate authority. While these certificates are not trusted by default, they can still provide an additional layer of security for communication between a client and a server.

Generating a self-signed certificate

To generate a self-signed certificate, we can use the openssl library in Python. First, make sure you have openssl installed on your machine. Then, use the following code to generate a self-signed certificate:

import subprocess

def generate_self_signed_cert():
    subprocess.run(["openssl", "req", "-x509", "-newkey", "rsa:4096", "-keyout", "key.pem", "-out", "cert.pem", "-days", "365", "-nodes"])

This code will use the openssl command-line tool to generate a self-signed certificate and a corresponding private key. The certificate will be valid for 365 days.

Socket programming with self-signed certificates

Once we have the self-signed certificate and the private key, we can use them in our Python socket programming code. Here’s an example of a server and client exchanging data over a secure SSL/TLS connection:

Server-side code:

import socket
import ssl

def start_server():
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("localhost", 8888))
    server_socket.listen()

    while True:
        client_socket, client_address = server_socket.accept()
        secure_client_socket = context.wrap_socket(client_socket, server_side=True)
        data = secure_client_socket.recv(1024)
        print("Received data from client:", data.decode())
        secure_client_socket.send("Hello from server!".encode())
        secure_client_socket.close()

Client-side code:

import socket
import ssl

def connect_to_server():
    context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
    context.load_verify_locations(cafile="cert.pem")

    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    secure_client_socket = context.wrap_socket(client_socket, server_hostname="localhost")
    secure_client_socket.connect(("localhost", 8888))
    secure_client_socket.send("Hello from client!".encode())
    data = secure_client_socket.recv(1024)
    print("Received data from server:", data.decode())
    secure_client_socket.close()

The server-side code sets up an SSL/TLS server using the self-signed certificate and private key. It listens for incoming connections and reads data from the client. The client-side code connects to the server using the self-signed certificate for verification.

Remember to replace "cert.pem" and "key.pem" with the respective paths to your generated certificate and private key files.

Conclusion

Using self-signed certificates for secure communication is an important aspect of cybersecurity. With the Python openssl library and socket programming, we can easily generate and use self-signed certificates to add an extra layer of protection to our network communications.

Keep in mind that while self-signed certificates provide encryption, they do not provide authentication of the server’s identity. For production environments, it is recommended to use certificates signed by trusted certificate authorities.