【发布时间】:2020-09-23 17:39:28
【问题描述】:
我正在使用python docs for WebSocket 中的示例进行安全 WebSocket 的简单 Python (3.8) 实现。这是在 Windows 10 计算机和连接到交换机/集线器的 Ubuntu 18.04.2 Linux 计算机之间。粗略的服务器和客户端代码如下:
服务器:
# WSS (WS over TLS) server example, with a self-signed certificate
import asyncio
import pathlib
import ssl
import websockets
async def hello(websocket, path):
name = await websocket.recv()
print(f"< {name}")
greeting = f"Hello {name}!"
await websocket.send(greeting)
print(f"> {greeting}")
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
localhost_pem = pathlib.Path(__file__).with_name("localhost.pem")
private_key = pathlib.Path(__file__).with_name("private.key")
ssl_context.load_cert_chain(localhost_pem,private_key)
start_server = websockets.serve(
hello, "164.123.456.2", 1234, ssl=ssl_context)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
客户:
# WSS (WS over TLS) client example, with a self-signed certificate
import asyncio
import pathlib
import ssl
import websockets
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
localhost_pem = pathlib.Path(__file__).with_name("localhost.pem")
private_key = pathlib.Path(__file__).with_name("private.key")
ssl_context.load_verify_locations(localhost_pem, private_key )
async def hello():
uri = "wss://164.123.456.2:1234"
async with websockets.connect(
uri, ssl=ssl_context
) as websocket:
name = input("What's your name? ")
await websocket.send(name)
print(f"> {name}")
greeting = await websocket.recv()
print(f"< {greeting}")
asyncio.get_event_loop().run_until_complete(hello())
我能够让这个实现与带有 IP 地址的主题备用名称 (SAN) 字段的自签名证书(使用 openssl 创建)一起使用。我想使用基于主机名而不是 IP 地址的证书。我在 SAN 证书字段中添加了“DNS Name =Hostname”,但这没有用。它导致以下错误:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for “164.123.456.2” (_ssl.c:1123)
这可能吗?应该在证书中添加哪些字段以使其工作?是否应该对 python 代码进行任何更改?
【问题讨论】:
标签: python-3.x ssl websocket ssl-certificate hostname