【发布时间】:2020-08-09 12:53:48
【问题描述】:
我正在使用 python 和 SSL 模块建立与服务器的 TLS 连接。然后我想向这个服务器发送一些数据。为此,我在一个名为“cert.pem”的文件中有一个CA-Certificate、客户端证书和客户端证书密钥。虽然我的服务器代码工作正常,但我的客户端代码无法连接到服务器。我只是模仿了SSL module example,我不明白为什么它会失败。
运行良好的服务器代码:
import socket, ssl
cert_chain = 'cert.pem'
host_addr = socket.gethostbyname(socket.gethostname())
host_port = 10023
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=cert_chain)
bindsocket = socket.socket()
bindsocket.bind((host_addr, host_port))
bindsocket.listen(5)
while True:
print("Waiting for client")
newsocket, fromaddr = bindsocket.accept()
conn = context.wrap_socket(newsocket, server_side=True)
print("SSL established. Peer: {}".format(conn.getpeercert()))
buf = b'' # Buffer to hold received client data
try:
while True:
data = conn.recv(4096)
if data: # Client sent us data. Append to buffer
buf += data
else: # No more data from client. Show buffer and close connection.
print("Received:", buf)
break
finally:
print("Closing connection")
conn.shutdown(socket.SHUT_RDWR)
conn.close()
失败的客户端代码:
import socket, ssl
server_addr = '**.***.***.***'
server_port = 3335
cert_chain = 'cert.pem'
context = ssl.create_default_context()
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=server_addr)
conn.connect((server_addr, server_port))
conn.send(b"Hello, world!")
conn.close()
当我运行客户端代码时,我得到这个错误:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)
但是,当我简单地使用this command 时,我可以发送数据:
openssl s_client -connect 127.0.0.1:10023
问题
- 我的客户端代码有什么问题?
- 为什么
openssl s_client命令有效而python 代码无效?
我非常感谢任何改进代码的建议。
【问题讨论】:
-
您尝试连接到端口
3335,但您的服务器侦听10023。 ;)
标签: python-3.x ssl openssl