Python httplib SSL23_GET_SERVER_HELLO: неизвестный протокол

Примечание: этот код отлично работает на Ubuntu, но не на Mac, и вместо того, чтобы изменять настройки mac / python локально, я пытаюсь внести изменения в код, чтобы он работал повсюду.

import ssl import httplib httplib.HTTPConnection(server, port, timeout) 

но он вызывает ошибку:

[Errno 1] _ssl.c: 503: error: 140770FC: SSL-процедуры: SSL23_GET_SERVER_HELLO: неизвестный протокол

теперь код не использует urllib.request вместо этого, используя httplib

Я хочу изменить код, поэтому в качестве протокола по умолчанию будет использоваться SSLv3, примерно так:

 ssl.SSLContext(ssl.PROTOCOL_SSLv3) 

Я огляделся и нашел несколько ссылок, но ничего не работает!

эта ссылка для ubuntu

ссылка для python urllib и cURL

ошибка исправления python, но опять же для urllib

Примечание. Конструктор HTTPSConnection позволяет передать ssl- context качестве аргумента с python 2.7.9, который следует использовать в этом случае.

Этот ответ предшествует этому изменению и поэтому применим только к устаревшим версиям python.


httplib.HTTPSConnection.connect просто вызывает ssl.wrap_socket в открытом соке, чтобы инициализировать https-соединение, к сожалению, вы не можете указать какие-либо параметры в python2.7 (python3 позволяет передавать SSLContext ).

Если вы хотите указать версию протокола, вам нужно установить патч обезьяны один из следующих:

Метод 1 : patch httplib.HTTPSConnection.connect :

 import httplib import socket import ssl def connect_patched(self): "Connect to a host on a given (SSL) port." sock = socket.create_connection((self.host, self.port), self.timeout, self.source_address) if self._tunnel_host: self.sock = sock self._tunnel() self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv3) httplib.HTTPSConnection.connect = connect_patched 

Это изменяет версию протокола для всех подключений, созданных с помощью HTTPSConnection .

Способ 2 : патч ssl.wrap_socket :

 import ssl wrap_socket_orig = ssl.wrap_socket def wrap_socket_patched(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_SSLv3, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None): return wrap_socket_orig(sock, keyfile, certfile, server_side, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, suppress_ragged_eofs, ciphers) ssl.wrap_socket = wrap_socket_patched 

Это изменяет версию протокола по умолчанию для всего кода, который использует wrap_socket , поэтому также влияет на другие библиотеки.

редактировать:

Способ 3 : поскольку httplib фактически обращается только к wrap_socket из ssl , вы также можете просто заменить httplib.ssl классом, предоставляющим wrap_socket . С помощью functools.partial очень удобно писать это:

 import httplib import ssl from functools import partial class fake_ssl: wrap_socket = partial(ssl.wrap_socket, ssl_version=ssl.PROTOCOL_SSLv3) httplib.ssl = fake_ssl