Python запрашивает с wincertstore - PullRequest
0 голосов
/ 19 мая 2018

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

import requests, socket, atexit, ssl, wincertstore
from requests.auth import HTTPBasicAuth
certfile = wincertstore.CertFile()
certfile.addstore("CA")
certfile.addstore("ROOT")
atexit.register(certfile.close)
ssl_sock = ssl.wrap_socket(s,ca_certs=certfile.name, 
cert_reqs=ssl.CERT_REQUIRED)
requests.get(url)

Я получаю следующую ошибку ................... requests.exceptions.SSLError: HTTPSConnectionPool(host='myhost', port=443): Max retries exceeded with url: myurl (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

Я могу использовать wget по той же ссылке и загружать контент.

wget --no check certificate --user=my username --password=my password URL

Но я не заинтересован в загрузке контента, так как мне нужно только очистить небольшую часть контента веб-страницы.

Pythin version = 3.6.5

Ссылка Wincertstore - Ссылка

Заранее благодарен за помощь ..............

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

У меня была похожая проблема, и я исправил ее с помощью пакета python-certifi-win32:

pip install python-certifi-win32

, теперь вы можете просто использовать:

requests.get(url, verify=True)

и сертификат проверяется с помощьюхранилище сертификатов Windows.

Редактировать: работает, только если сертификат установлен в хранилище сертификатов Windows ...

0 голосов
/ 20 мая 2018

Все это объясняется в разделе Проверка сертификата SSL документа requests.

По умолчанию requests использует сертификаты certifi если присутствует, то возврат к тому, что urllib3 думает, является хранилищем сертификатов вашей ОС, которое само по себе возвращается к тому, о чем думает Python (хотя в старых версиях это часто не было).

Ваша компания, очевидно, имеетчастный, возможно, даже самоподписанный сертификат, который не будет в certifi. может находиться в хранилище сертификатов Windows - в этом случае urllib3 должно автоматически его забрать, но я подозреваю, что это не так.Возможно, сертификат устанавливается непосредственно в какую-то пользовательскую настройку браузера, которую ваш ИТ-отдел заставляет использовать, а не в магазин ОС.Или, может быть, он не установлен вообще.(Вы не упоминали о возможности доступа к этому сайту в браузере, не увидев значок сломанного замка…)

Вы передаете --no check certificate (или, более вероятно, --no-check-certificate?) На wget, поэтому вы просто не проверяете SSL.И если вы хотите сделать то же самое в requests, это просто:

requests.get(url, verify=False)

Если вы уверены, что у вас установлен сертификат, даже если wget может 'не могу найти его ... ну, ваш код не будет работать так, как написано.Вот что будет работать:

  • Игнорируйте сертификат и просто отключите проверку, как показано выше.
  • Определите, где на самом деле установлен соответствующий сертификат и как его загрузить, и:
    • Передавайте его в качестве аргумента verify при каждом requests вызове.
    • Установите его где-нибудь статически и передайте в переменной окружения.
    • Установите его по умолчаниюхранилище сертификатов, чтобы все работало автоматически.
    • Напишите HTTPAdapter, который установит его в ваш requests сеанс.

Сначала ваш кодпросто пытается получить сертификат по умолчанию точно так же, как это делает Python.Этот модуль wincertstore является всего лишь бэкпортом того, что уже встроено в Python 3.4+.

Во-вторых, весь ваш код делает получение сертификата, используя его для создания сокета SSL,игнорируя этот сокет, и приказывая requests делать все как обычно.Это ничего не поможет.Если вы хотите передать сертификат на requests, вы должны сделать это:

requests.get(url, verify='/path/to/cert')

… или поместить его в переменную окружения REQUESTS_CA_BUNDLE

… или сделать HTTPAdapterкод, который я показал вам в чате (и который вы нашли в старой, нерабочей версии, где-то не указано).См. HTTPAdapter в документации, если вы действительно хотите это сделать.

...