Как получить сертификат SSL-ответа от запросов в python?

Попытка получить сертификат SSL из ответа в requests .

Каков хороший способ сделать это?

Огромное спасибо!

2 Solutions collect form web for “Как получить сертификат SSL-ответа от запросов в python?”

requests преднамеренно завершают низкоуровневые вещи вроде этого. Как правило, единственное, что вы хотите сделать, это убедиться, что сертификаты действительны . Для этого просто выполните verify=True . Если вы хотите использовать нестандартный пакет cacert, вы также можете передать это. Например:

 resp = requests.get('https://example.com', verify=True, cert=['/path/to/my/ca.crt']) 

Кроме того, requests – это, прежде всего, набор оберток вокруг других библиотек, в основном urllib3 и http.client http.client (или, для 2.x, httplib ) и ssl .

Иногда ответ заключается только в том, чтобы попасть на объекты более низкого уровня (например, resp.raw – это urllib3.response.HTTPResponse ), но во многих случаях это невозможно.

И это один из таких случаев. Единственными объектами, которые когда-либо видели сертификаты, является http.client.HTTPSConnection (или urllib3.connectionpool.VerifiedHTTPSConnection , но это только подкласс первого) и ssl.SSLSocket , и ни один из них больше не существует к моменту запроса возвращается. (Как следует из названия connectionpool , объект HTTPSConnection хранится в пуле и может быть повторно использован, как только это будет сделано, SSLSocket является членом HTTPSConnection .)

Итак, вам нужно исправить все, чтобы вы могли скопировать данные по цепочке. Это может быть так просто:

 HTTPResponse = requests.packages.urllib3.response.HTTPResponse orig_HTTPResponse__init__ = HTTPResponse.__init__ def new_HTTPResponse__init__(self, *args, **kwargs): orig_HTTPResponse__init__(self, *args, **kwargs) try: self.peercert = self._connection.sock.getpeercert() except AttributeError: pass HTTPResponse.__init__ = new_HTTPResponse__init__ HTTPAdapter = requests.adapters.HTTPAdapter orig_HTTPAdapter_build_response = HTTPAdapter.build_response def new_HTTPAdapter_build_response(self, request, resp): response = orig_HTTPAdapter_build_response(self, request, resp) try: response.peercert = resp.peercert except AttributeError: pass return response HTTPAdapter.build_response = new_HTTPAdapter_build_response 

Это непроверено, поэтому никаких гарантий; вам, возможно, придется исправлять больше.

Кроме того, подклассы и переопределение, вероятно, будут более чистыми, чем monkeypatching (тем более, что HTTPAdapter был разработан для подкласса).

Или, что еще лучше, urllib3 и requests , изменяя вашу вилку, и (если вы считаете, что это законно полезно), отправляя запросы на выходы вверх по течению.

В любом случае, теперь из вашего кода вы можете сделать это:

 resp.peercert 

Конечно, вы также можете передать всю информацию, необходимую для проверки сертификата, но это еще проще, потому что оно уже проходит через верхний уровень.

Это, хотя и не очень-то, работает:

 import requests req = requests.get('https://httpbin.org') pool = req.connection.poolmanager.connection_from_url('https://httpbin.org') conn = pool.pool.get() # get() removes it from the pool, so put it back in pool.pool.put(conn) print(conn.sock.getpeercert()) 
  • HTTPS войти в систему с urllib2
  • Запрос HTTPS в Python
  • Прокси HTTPS с запросами: _ssl.c: 504: EOF произошел с нарушением протокола
  • python-requests 2.0.0 - _ssl.c: 504: EOF произошел с нарушением протокола
  • Как импортировать _ssl в python 2.7.6?
  • Запрос SOAP Python с использованием urllib2
  • Как работает Python urllib2 https?
  • Механизация Python не работает, когда требуются HTTPS и прокси-аутентификация
  • Python - лучший язык программирования в мире.