简体   繁体   English

Python客户端 - SSL lib - 证书验证失败

[英]Python client - SSL lib - certificate verify failed

I'm trying to do a small secure HTTPS client for learning purposes and see how all the mechanics of SSL works on a higher level for now, so i'm trying to convert a simple socket into a ssl via ssl.wrap_socket. 我正在尝试为学习目的做一个小型安全HTTPS客户端,看看SSL的所有机制现在如何在更高层次上工作,所以我试图通过ssl.wrap_socket将一个简单的套接字转换为ssl。

I probably got the whole concept backwards but, here's what i'm doing: 我可能倒退了整个概念但是,这就是我正在做的事情:

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()

And when i call do_handshake() i get this: 当我调用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

I've searched around for a while and tried for find something that would be close to what i do, but everyone points to either PyOpenSSL or Twisted and i'd prefer if i could stay out of those libraries, mainly because later on i'm planing on bringing this into a sharp production environment where i'm only allowed to use the built in libraries of Python2.6. 我已经搜索了一段时间,并试图找到一些与我的工作接近的东西,但每个人都指向PyOpenSSL或Twisted,我更喜欢我是否可以不在这些库中,主要是因为后来我我计划将其带入一个敏锐的生产环境,我只允许使用Python2.6的内置库。

Any help would be greatful! 任何帮助都会很棒!

The problem here is that you can't validate a certificate with itself (that is what you are trying to do) unless it is self-signed, and has a CA bit set. 这里的问题是你不能用自己验证证书(这是你想要做的),除非它是自签名的,并且设置了CA位。 You should add a real CA certificate of the web site to the cacerts.txt file. 您应该将该网站的真实CA证书添加到cacerts.txt文件中。 Another alternative (something like "connect anyway" in a web browser) is to drop the cert_reqs to ssl.CERT_NONE after you get such exception, and understand that there could possibly be a man in the middle. 另一种替代方法(在Web浏览器中类似“无论如何连接”)是在获得此类异常后将cert_reqsssl.CERT_NONE ,并了解中间可能有一个人。 This is not the ssl module issue, this is how SSL/X.509 work. 这不是ssl模块的问题,这就是SSL / X.509的工作原理。

If you are just learning, you can also use Anonymous Diffie-Hellman , that is a server doesn't have a certificate at all, and your client doesn't care to validate it. 如果您刚刚学习,您也可以使用Anonymous Diffie-Hellman ,即服务器根本没有证书,而您的客户端并不关心验证它。

Below is a simple (and insecure) test. 下面是一个简单(和不安全)的测试。

Test server, courtesy of openssl package: 测试服务器,由openssl包提供:

openssl s_server  -nocert -cipher "ALL:aNULL:eNULL"

Test client in Python : Python测试客户端:

...
ssl.wrap_socket(..., ciphers="ALL:aNULL:eNULL")
...

-- -

If you want to play with certificates, openssl package can generate what you want, but it's a bit tricky to get it right. 如果你想玩证书, openssl包可以生成你想要的东西,但要正确使用它有点棘手。 Good GUI tool is TinyCA , it's written in perl and uses openssl commands, but offers you a decent framework to create own CAs, sign own certificates, etc. 好的GUI工具是TinyCA ,它是用perl编写的并使用openssl命令,但为您提供了一个很好的框架来创建自己的CA,签署自己的证书等。

If you're in a hurry, just install apache, start it up, your distro (linux or wamp) will most likely create a self-signed certificate to get you started. 如果你赶时间,只需安装apache,启动它,你的发行版(linux或wamp)很可能会创建一个自签名证书来帮助你入门。 Configure apache to the point where you can connect to https://localhost with a browser. 将apache配置为可以使用浏览器连接到https://localhost的位置。 Then use that server to connect to, I think you will get by if you add server's self-signed CA to your clients CA list/file. 然后使用该服务器进行连接,如果您将服务器的自签名CA添加到客户端CA列表/文件中,我认为您将顺便通过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM