Python 3.x 如何创建Python安全websocket客户端请求?
我的Python安全websocket客户端代码给了我以下异常:Python 3.x 如何创建Python安全websocket客户端请求?,python-3.x,websocket,openssl,tornado,azure-web-app-service,Python 3.x,Websocket,Openssl,Tornado,Azure Web App Service,我的Python安全websocket客户端代码给了我以下异常: import json from websocket import create_connection class subscriber: def listenForever(self): try: # ws = create_connection("wss://localhost:9080/websocket") ws = create_connection("wss://nbtstagi
import json
from websocket import create_connection
class subscriber:
def listenForever(self):
try:
# ws = create_connection("wss://localhost:9080/websocket")
ws = create_connection("wss://nbtstaging.westeurope.cloudapp.azure.com:9090/websocket")
ws.send("test message")
while True:
result = ws.recv()
result = json.loads(result)
print("Received '%s'" % result)
ws.close()
except Exception as ex:
print("exception: ", format(ex))
try:
subscriber().listenForever()
except:
print("Exception occured: ")
import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import os
import ssl
ssl_root = os.path.join(os.path.dirname(__file__), 'ssl1_1020')
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
pass
def on_message(self, message):
self.write_message("Your message was: " + message)
print("message received: ", format(message))
def on_close(self):
pass
class IndexPageHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', IndexPageHandler),
(r'/websocket', WebSocketHandler),
]
settings = {
'template_path': 'templates'
}
tornado.web.Application.__init__(self, handlers, **settings)
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(ssl_root+"/server.crt",
ssl_root + "/server.pem")
if __name__ == '__main__':
ws_app = Application()
server = tornado.httpserver.HTTPServer(ws_app, ssl_options=ssl_ctx,)
server.listen(9081, "0.0.0.0")
print("server started...")
tornado.ioloop.IOLoop.instance().start()
[SSL:CERTIFICATE\u VERIFY\u FAILED]证书验证失败(\u SSL.c:748)
我已经创建了我的私有证书和签名证书,但我无法使用Python脚本连接到它,如下所示:
import json
from websocket import create_connection
class subscriber:
def listenForever(self):
try:
# ws = create_connection("wss://localhost:9080/websocket")
ws = create_connection("wss://nbtstaging.westeurope.cloudapp.azure.com:9090/websocket")
ws.send("test message")
while True:
result = ws.recv()
result = json.loads(result)
print("Received '%s'" % result)
ws.close()
except Exception as ex:
print("exception: ", format(ex))
try:
subscriber().listenForever()
except:
print("Exception occured: ")
import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import os
import ssl
ssl_root = os.path.join(os.path.dirname(__file__), 'ssl1_1020')
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
pass
def on_message(self, message):
self.write_message("Your message was: " + message)
print("message received: ", format(message))
def on_close(self):
pass
class IndexPageHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', IndexPageHandler),
(r'/websocket', WebSocketHandler),
]
settings = {
'template_path': 'templates'
}
tornado.web.Application.__init__(self, handlers, **settings)
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(ssl_root+"/server.crt",
ssl_root + "/server.pem")
if __name__ == '__main__':
ws_app = Application()
server = tornado.httpserver.HTTPServer(ws_app, ssl_options=ssl_ctx,)
server.listen(9081, "0.0.0.0")
print("server started...")
tornado.ioloop.IOLoop.instance().start()
我用python编写的https/wss服务器脚本和tornado,如下所示:
import json
from websocket import create_connection
class subscriber:
def listenForever(self):
try:
# ws = create_connection("wss://localhost:9080/websocket")
ws = create_connection("wss://nbtstaging.westeurope.cloudapp.azure.com:9090/websocket")
ws.send("test message")
while True:
result = ws.recv()
result = json.loads(result)
print("Received '%s'" % result)
ws.close()
except Exception as ex:
print("exception: ", format(ex))
try:
subscriber().listenForever()
except:
print("Exception occured: ")
import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import os
import ssl
ssl_root = os.path.join(os.path.dirname(__file__), 'ssl1_1020')
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
pass
def on_message(self, message):
self.write_message("Your message was: " + message)
print("message received: ", format(message))
def on_close(self):
pass
class IndexPageHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', IndexPageHandler),
(r'/websocket', WebSocketHandler),
]
settings = {
'template_path': 'templates'
}
tornado.web.Application.__init__(self, handlers, **settings)
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(ssl_root+"/server.crt",
ssl_root + "/server.pem")
if __name__ == '__main__':
ws_app = Application()
server = tornado.httpserver.HTTPServer(ws_app, ssl_options=ssl_ctx,)
server.listen(9081, "0.0.0.0")
print("server started...")
tornado.ioloop.IOLoop.instance().start()
用于创建SSL签名证书的步骤:
openssl genrsa -des3 -out server.key 1024
openssl rsa -in server.key -out server.pem
openssl req -new -nodes -key server.pem -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.pem -out server.crt
最后我找到了一个解决方案,我更新了python客户端脚本,同时连接到安全web套接字url以忽略证书请求,如下所示:
import ssl
import websocket
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect("wss://xxx.com:9090/websocket")
如果将来有人想知道wss python服务器失败的原因是因为tornado文档中的这一点: 使用带有自签名证书的安全websocket连接(wss://)时,来自浏览器的连接可能会失败,因为它希望显示“接受此证书”对话框,但无处显示。在websocket连接成功之前,必须首先使用相同的证书访问常规HTML页面以接受它
对我来说,忽略错误不是一个选项,我不得不使用我的自签名证书,因为SSL固定在复杂的物联网环境中:
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())
导入异步IO
导入路径库
导入ssl
导入WebSocket
ssl\u context=ssl.SSLContext(ssl.PROTOCOL\u TLS\u客户端)
localhost\u pem=pathlib.Path(\uuuu文件\uuuuu)。名称为(“localhost.pem”)
ssl\u上下文。加载\u验证\u位置(本地主机\u pem)
异步def hello():
uri=”wss://localhost:8765"
与websockets.connect异步(
uri,ssl=ssl\U上下文
)作为websocket:
name=输入(“你叫什么名字?”)
等待websocket.send(名称)
打印(f“>{name}”)
问候语=等待websocket.recv()
打印(f“<{问候语}”)
asyncio.get_event_loop()。运行_直到完成(hello())
在websocket repo的示例文件夹中找到了它
附笔
我将其从
SSLContext(ssl.PROTOCOL\u TLS\u CLIENT)
更改为SSLContext(ssl.PROTOCOL\u TLSv1\u 2)
,以使其正常工作仅出于测试目的尝试以下内容。以下是一个高度不安全的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}")
导入异步IO、ssl、WebSocket
#托多·克鲁格
#高度不安全
ssl\u context=ssl.SSLContext()
ssl\u context.check\u hostname=False
ssl\u context.verify\u mode=ssl.CERT\u NONE
#高度不安全
#托多·克鲁格
uri=”wss://myAwesomeSSL.wss.kluge"
与websocket.connect异步(uri,ssl=ssl\U上下文)作为websocket:
问候语=等待websocket.recv()
打印(f“<{问候语}”)
您使用MacOS吗?更可能是系统权限有问题,您可能需要将证书添加到密钥链。。。您可能想查看这篇文章否,它都是Linux ubuntu 16.04 env os。有类似问题的人:例如,如果websocket位于localhost:4000
,您必须访问https://localhost:4000
并接受风险。