Python请求客户端证书-握手失败

时间:2019-01-24 16:36:50

标签: python-2.7 ssl python-requests pyopenssl ssl-client-authentication

我正在尝试向受客户端证书保护的服务器发出请求。我正在使用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),并确保私钥是第一位的。

我还尝试卸载并安装这些库,以确保我具有最新版本。

希望听到一些想法。

0 个答案:

没有答案