Python中的SSL:为什么它不向服务器发送证书?

时间:2011-06-25 12:00:46

标签: python ssl ssl-certificate x509 handshake

我正在编写一些应该从SSL安全网页获取信息的软件。下面是我用来连接服务器的一段代码。

s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket (
    s,
    ca_certs = '/home/stilz/Desktop/Certyfikaty/GLOWNE_CA.cer',
    cert_reqs = ssl.CERT_REQUIRED,
    ssl_version = ssl.PROTOCOL_SSLv3,
)
ssl_sock.connect ((HOST, PORT))

然而,这不起作用。它会在消息“握手警报失败”时抛出异常。我捕获了一些来自我的脚本的TCP数据包以及来自Internet Explorer的相应数据包,并发现我的脚本根本没有发送证书(服务器返回类似“致命:没有提供证书”),而IE正常发送它。据我所知,文件ca.cer是x509证书(以“----- BEGIN CERTIFICATE -----”开头)。

请帮助我,告诉我我做错了什么。如果我提供的信息很少,请告诉我。

此致

2 个答案:

答案 0 :(得分:1)

首先,您需要确定是否需要在服务器上对自己进行身份验证(仅在此情况下将证书发送到服务器),或者您需要验证服务器的真实性(在这种情况下,证书不会发送到服务器)服务器)。

现在关于代码中的问题:

案例1:您无需在服务器上进行身份验证。在这种情况下,您无需指定证书,也不会向服务器发送任何内容。

案例2:您需要在服务器上进行身份验证。在这种情况下,您需要在keyfile和certfile参数中提供证书和私钥文件。只有这样,您的证书才会被发送到服务器(并且在握手中使用私钥)。

我猜你的情况实际上是1。首先,您需要通过使用Web浏览器连接到服务器并检查站点的证书链来检查服务器是否提供有效证书。可能会发生该站点发送其证书但省略中间CA证书。

无论如何,我想提醒一下我建议您重新阅读的discussion about certificates in Python docs

答案 1 :(得分:0)

如果服务器请求(并要求)客户端发送证书,则需要向ssl.wrap_socket提供您的证书(certfile)的路径,并且其匹配的私钥(keyfile)。 ca_certs参数仅用于客户端根据已知CA证书验证服务器的证书,它与发送客户端证书无关。

您可能需要从IE导出客户端证书和私钥(然后将其转换为PEM格式)。