My Python secure websocket client code giving me exception as follows:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
For me, ignoring the errors is not an options, I had to use my self signed certificate because of SSL pinning in a complex IoT environment:
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")
ssl_context.load_verify_locations(localhost_pem)
async def hello():
uri = "wss://localhost:8765"
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())
Found it here on the websocket repo's examples folder.
I changed it from SSLContext(ssl.PROTOCOL_TLS_CLIENT)
to SSLContext(ssl.PROTOCOL_TLSv1_2)
to make it work
If anyone is curious in the future why wss python server fails is because of this right here in the tornado documentation:
When using a secure websocket connection (wss://) with a self-signed certificate, the connection from a browser may fail because it wants to show the “accept this certificate” dialog but has nowhere to show it. You must first visit a regular HTML page using the same certificate to accept it before the websocket connection will succeed.
Only try the below for testing purposes only. The below is a highly insecure kluge:
import asyncio, ssl, websockets
#todo kluge
#HIGHLY INSECURE
ssl_context = ssl.SSLContext()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
#HIGHLY INSECURE
#todo kluge
uri = "wss://myAwesomeSSL.wss.kluge"
async with websockets.connect(uri, ssl=ssl_context) as websocket:
greeting = await websocket.recv()
print(f"< {greeting}")
Finally I found a solution, I updated python client script while making connection to secure web socket url to ignore cert request as follows:
import ssl
import websocket
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect("wss://xxx.com:9090/websocket")