Python запрашивает клиентские сертификаты - сбой рукопожатия - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь сделать запрос к серверу, который защищен сертификатом на стороне клиента. Я использую запросы 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), и застраховал закрытый ключ первым.

Я также пытался удалить и установить библиотеки, чтобы убедиться, что у меня самые новые версии.

Надеюсь услышать некоторые идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...