我正在尝试向受客户端证书保护的服务器发出请求。我正在使用Python请求。问题是,我无法进行握手。我已经与邮递员进行了测试,在那儿我设置了证书和钥匙。可行。
我认为这是由于证书和密钥的设置方式引起的,但我不确定。代码如下:
headers = {'Content-Type': 'text/xml'}
uri = 'https//:some_uri.com'
cert_path = '../xxxx.cer'
key_path = '../xxxx.key'
data = '<?xml version='1.0' encoding='UTF-8'?>'
server_hostname = some_uri.com
response = requests.post(uri, data=data, headers=headers, cert=(cert_path, key_path), verify=False, timeout=10)
我遇到以下错误:
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 555, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 490, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', error(0, 'Error'))
我已经尝试了一个更底层的解决方案:
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(cert[0])
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
conn = httplib.HTTPSConnection(server_hostname, port=443, context=context, cert_file=cert_path, key_file=key_path)
conn.request("POST", "/", body=data, headers=headers)
response = conn.getresponse()
或
context = ssl._create_unverified_context(certfile=cert_path, keyfile=key_path)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=server_hostname)
conn.connect((server_hostname, 443))
这两个低级解决方案都给出以下错误(跟踪日志中的微小变化)。 :
File "/usr/lib/python2.7/httplib.py", line 1042, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.7/httplib.py", line 1082, in _send_request
self.endheaders(body)
File "/usr/lib/python2.7/httplib.py", line 1038, in endheaders
self._send_output(message_body)
File "/usr/lib/python2.7/httplib.py", line 882, in _send_output
self.send(msg)
File "/usr/lib/python2.7/httplib.py", line 844, in send
self.connect()
File "/usr/lib/python2.7/httplib.py", line 1263, in connect
server_hostname=server_hostname)
File "/usr/lib/python2.7/ssl.py", line 369, in wrap_socket
_context=self)
File "/usr/lib/python2.7/ssl.py", line 617, in __init__
self.do_handshake()
File "/usr/lib/python2.7/ssl.py", line 846, in do_handshake
self._sslobj.do_handshake()
error: [Errno 0] Error
它们都在python 2.7 ssl.py lib中的握手时失败:
def do_handshake(self, block=False):
"""Perform a TLS/SSL handshake."""
self._check_connected()
timeout = self.gettimeout()
try:
if timeout == 0.0 and block:
self.settimeout(None)
self._sslobj.do_handshake()
finally:
self.settimeout(timeout)
if self.context.check_hostname:
if not self.server_hostname:
raise ValueError("check_hostname needs server_hostname "
"argument")
match_hostname(self.getpeercert(), self.server_hostname)
如果证书和密钥无效,则该行为似乎正确。然后服务器什么都不响应,但是如何在邮递员而不是python代码中工作呢?是需要设置证书的方式吗?我也尝试过使用一个文件(.pem),并确保私钥是第一位的。
我还尝试卸载并安装这些库,以确保我具有最新版本。
希望听到一些想法。