Openssl + Socket 加密通信及证书配置【Python】


使用 openssl 和 socket 实现 Client/Server 加密通信的简易测试程序。

1 证书配置

新建目录 cert ,用于存储证书文件。

1.1 创建 CA 证书

首先配置并创建 CA 证书,CA 证书配置文件 ca.conf

[ req ]
default_bits       = 2048
default_md         = sha256
distinguished_name = req_distinguished_name
x509_extensions    = v3_ca
prompt             = no

[ req_distinguished_name ]
C  = CN
ST = HN
L  = SomeCity
O  = MyCompany
OU = MyDivision
CN = MyRootCA

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

生成私钥 ca.key 并创建 CA 证书 ca.crt

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt -config ca.conf

查看证书的细节信息:

openssl x509 -in ca.crt -text -noout

部分显示如下:

CA证书信息

1.2 创建服务器证书

同理,服务器证书配置文件 server.conf

[ req ]
default_bits       = 2048
default_md         = sha256
distinguished_name = req_distinguished_name
req_extensions     = v3_req
prompt             = no

[ req_distinguished_name ]
C  = CN
ST = HN
L  = SomeCity
O  = MyCompany
OU = MyDivision
CN = 127.0.0.1

[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost
IP.1 = 127.0.0.1
IP.2 = 192.168.26.170

生成服务器私钥 server.key 和证书请求 server.csr :

openssl req -new -nodes -newkey rsa:2048 -keyout server.key -out server.csr -config server.conf

使用 CA 签署服务器证书:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extensions v3_req -extfile server.conf

查看服务器证书 server.crt 的细节信息:

openssl x509 -in server.crt -text -noout

部分显示结果如下:

服务器证书信息

2 加密通信

2.1 服务器端

# server.py

import socket
import ssl


ip_port = ('127.0.0.1', 9443)

# 生成 SSL 上下文
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
# 加载服务器所用证书和私钥
context.load_cert_chain('cert/server.crt', 'cert/server.key')

# 创建 socket 并打包成 SSL socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket = context.wrap_socket(server_socket, server_side=True)

# 监听端口
server_socket.bind(ip_port)
server_socket.listen(5)

while True:
    # 接收客户端连接
    client_socket, addr = server_socket.accept()
    # 接收客户端信息
    msg = client_socket.recv(1024).decode("utf-8")
    print(f"receive msg from client {addr}: {msg}")
    # 向客户端发送信息
    msg = f"Hello, I am server.\r\n".encode("utf-8")
    client_socket.send(msg)
    # 关闭连接
    client_socket.close()

2.2 客户端

# client.py

import socket
import ssl


ip_port = ('127.0.0.1', 9443)

# 生成SSL上下文
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# 加载信任根证书
context.load_verify_locations('cert/ca.crt')

# 创建 socket 并打包成 SSL socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 注意这里的 server_hostname 不是指服务端IP,而是指服务端证书中设置的 CN
client_socket = context.wrap_socket(client_socket, server_hostname='127.0.0.1')

# 与服务端建立连接
client_socket.connect(ip_port)

# 向服务端发送消息
msg = "Hello server, I am client.\n"
client_socket.send(msg.encode('utf-8'))
print(f"send msg to server {ip_port}: {msg}")

# 接受服务端返回的消息
msg = client_socket.recv(1024).decode("utf-8")
print(f"receive msg from server : {msg}")

client_socket.close()

2.3 运行结果

打开两个终端,一个运行 server.py,一个运行 client.py,运行结果如下图所示:

运行结果

  1. 客户端向服务器发送消息 “Hello server, I am client.”
  2. 服务器收到来自客户端的消息并响应
  3. 客户端收到来自服务器的回复消息 “Hello, I am server.”
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值