Python SSL 服务器 SSLSocket 在 Safari 和 Firefox 中访问时出现 SSLError

3 投票
1 回答
1923 浏览
提问于 2025-04-17 14:55

我正在为一个课程写一个简单的服务器,其中有一个“创意”部分,所以我想给它加上SSL。现在我试着用SSLSocket来包装连接,但遇到了两个不同的错误,我搞不清楚是什么情况。第一个错误出现在Safari上,当我试图包装这个socket时,出现了:

Traceback (most recent call last):
  File "./junk.py", line 12, in <module>
    connstream = ssl.wrap_socket(connected_socket,certfile="cert.pem",keyfile="cert.pem",server_side=True,cert_reqs=ssl.CERT_NONE,ssl_version=ssl.PROTOCOL_TLSv1,suppress_ragged_eofs=True)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 372, in wrap_socket
    ciphers=ciphers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 134, in __init__
    self.do_handshake()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 296, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [Errno 8] _ssl.c:503: EOF occurred in violation of protocol

Safari告诉用户证书无效(我通过命令:openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem创建了一个自签名证书),然后当我告诉它这个证书没问题后,下一次就能正常通过了。

但是,在Firefox上,我遇到了完全不同的错误,这个错误发生在我试图读取客户端(Firefox)发送给服务器的数据时:

Traceback (most recent call last):
  File "./junk.py", line 13, in <module>
    recieved = connstream.read() 
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 151, in read
    return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1354: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

下面是我使用的代码:

  1 #!/usr/bin/python
  2 import socket
  3 import ssl
  4 
  5 serverPort = 22222
  6 serverSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
  7 serverSocket.bind( ( '127.0.0.1', serverPort ) )
  8 serverSocket.listen( 10 )
  9 
 10 while True:
 11     connected_socket, from_addr = serverSocket.accept()
 12     connstream = ssl.wrap_socket(connected_socket,certfile="cert.pem",keyfile="cert.pem",server_side=True,cert_reqs=ssl.CERT_NONE,ssl_version=ssl.PROTOCOL_TLSv1,suppress_ragged_eofs=True)
 13     recieved = connstream.read()
 14     print recieved
 15     connstream.unwrap()
 16     connected_socket.close()

有没有人能帮我理解:

1) 这些错误是什么意思

2) 为什么会出现这些错误

3) 我该如何解决这些问题

(我几乎用尽了所有能想到的方法进行搜索)

谢谢,

安德鲁

1 个回答

2

抱歉,我还不能评论,这不是一个答案。

为什么总是要重新发明轮子呢?我的意思是,如果你想要一个基于Python的东西,为什么不直接用Tornado呢?顺便说一下,你可以看看他们是怎么解决这个问题的:http://www.tornadoweb.org/documentation/httpserver.html

人们总是因为“学习目的”或者觉得现有的解决方案太“臃肿”、“沉重”等等而重新发明轮子(总的来说就是“这里没我发明的”)。这真是可惜,因为同样的事情一遍又一遍地做,通常都是错的。

Safari不支持握手,肯定是因为你的证书是自签名的。Firefox也不接受你的证书,因为它是自签名的。这些错误是正常的:用户必须在浏览器中接受“受信任”的连接。与此同时,你的服务器没有收到任何回应或者被拒绝。

看看Tornado是怎么处理这个问题的。但我真的觉得你最好是去学习它,使用它,并为它做贡献,而不是自己创建一个全新的、半成品的HTTP服务器。

撰写回答