我正在尝试为学习目的做一个小型安全HTTPS客户端,看看SSL的所有机制现在如何在更高层次上工作,所以我试图通过ssl.wrap_socket将一个简单的套接字转换为ssl
我可能倒退了整个概念但是,这就是我正在做的事情:
s.connect((host, port))
if port == 443:
f = open('cacerts.txt', 'r')
calist = f.read()
f.close()
ca = ssl.get_server_certificate((host, port), ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1)
if not ca in calist:
f = open('cacerts.txt', 'a')
f.write(ca)
f.close()
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1, cert_reqs=ssl.CERT_REQUIRED, ca_certs="cacerts.txt")
s.do_handshake()
当我打电话给do_handshake()时,我得到了这个:
Traceback (most recent call last):
File "SSL_test.py", line 84, in Requester
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1, cert_reqs=ssl.CERT_REQUIRED, ca_certs="cacerts.txt")
File "C:\Python26\lib\ssl.py", line 338, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs)
File "C:\Python26\lib\ssl.py", line 120, in __init__
self.do_handshake()
File "C:\Python26\lib\ssl.py", line 279, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:490: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
我已经搜索了一段时间,并试图找到一些与我所做的相近的东西,但是每个人都指向PyOpenSSL或Twisted,我更喜欢如果我可以不在这些库中,主要是因为以后我正计划将其带入一个敏锐的生产环境,我只允许使用Python2.6的内置库。
任何帮助都会很棒!
答案 0 :(得分:9)
这里的问题是你不能用自己验证证书(这是你想要做的),除非它是自签名的,并且设置了CA位。您应该将该网站的真实CA证书添加到cacerts.txt
文件中。另一种选择(类似于在网络浏览器中“无论如何连接”)是在你得到这样的例外之后将cert_reqs
放到ssl.CERT_NONE
,并且理解中间可能有一个人。这不是ssl
模块问题,这是SSL / X.509的工作方式。
答案 1 :(得分:1)
如果您刚学习,也可以使用Anonymous Diffie-Hellman,即服务器根本没有证书,而您的客户也不关心验证它。
以下是一个简单(且不安全)的测试。
测试服务器,由openssl
包提供:
openssl s_server -nocert -cipher "ALL:aNULL:eNULL"
在Python
中测试客户:
...
ssl.wrap_socket(..., ciphers="ALL:aNULL:eNULL")
...
-
如果您想使用证书,openssl
包可以生成您想要的内容,但要正确使用它有点棘手。好的GUI工具是TinyCA
,它是用perl编写的并使用openssl命令,但为你提供了一个很好的框架来创建自己的CA,签署自己的证书等。
如果你赶时间,只需安装apache,启动它,你的发行版(linux或wamp)很可能会创建一个自签名证书来帮助你入门。将apache配置为可以使用浏览器连接到https://localhost
的位置。然后使用该服务器进行连接,我想如果您将服务器的自签名CA添加到客户端CA列表/文件中,您将会过得很快。