В Python3.6.5 запрашивает ошибку SSL-сертификата - PullRequest
0 голосов
/ 22 февраля 2019

Я пытался получить следующий URL-адрес с помощью запросов, но получаю ошибку SSL-сертификата.Я перепробовал все предыдущие запросы переполнения стека, но ничего не работает. Код:

resp = requests.get('https://www.magidglove.com/', verify=certifi.where())

Я дал подтверждение = Ложь, все еще не работает

Ошибка:

    raise MaxRetryError(_pool, url, error or ResponseError(cause))urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.magidglove.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

TL; DR - сервер неправильно настроен.Либо исправьте сервер, передайте verify=ssl.CERT_NONE, либо загрузите и передайте сертификат www.magidglove.com явно.

Проблема здесь на сервере, а не на клиенте.Сервер настроен только на возврат своего собственного сертификата, чего недостаточно для того, чтобы клиент доверял ему.Обычно серверы должны быть настроены на возврат полной цепочки сертификатов.

Чтобы диагностировать это, вы можете использовать openssl для просмотра некоторой необработанной информации о возвращенной цепочке сертификатов:

$ openssl s_client -connect www.google.com:443 -showcerts -servername www.google.com

CONNECTED(00000003)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
... snipped the rest of the output ...

Вы видите, что 3 сертификата были возвращены сервером, и они были проверены в обратном порядке.Сертификат GlobalSign является доверенным для библиотеки certifi, сертификат на depth=1 был создан сертификатом на depth=2, а последний сертификат CN=www.google.com был создан сертификатом на depth=1.

Теперь давайте сравним это с сервером, к которому вы пытались подключиться:

$ openssl s_client -connect www.magidglove.com:443 -showcerts -servername www.magidglove.com

CONNECTED(00000003)
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=21:unable to verify the first certificate
verify return:1

Из этого вывода вы можете увидеть несколько вещей: - Сервер вернул только один сертификат - Клиентпопытался проверить сертификат и не смог

Требуется некоторое знание ssl, чтобы понять, что причина, по которой он не мог проверить, заключалась в том, что он не доверяет сертификату, но теперь, когда мы знаем, что мыможно увидеть, что возвращение сервером полной цепочки сертификатов исправит это.Я подозреваю, что причина, по которой Chrome и другие браузеры не сообщают об ошибке, заключается в том, что сам браузер знает о DigiCert, поэтому он не требует полной цепочки.

0 голосов
/ 22 февраля 2019

Эту проблему легко решить, добавив импорт ssl в ваш код Python и добавив verify=ssl.CERT_NONE, чтобы ваш код выглядел примерно так:

import requests
import ssl

resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

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

/ Library / Frameworks / Python.framework / Versions / 3.6 / lib / python3.6 / site-packages / urllib3 / connectionpool.py: 858:InsecureRequestWarning: выполняется непроверенный HTTPS-запрос.Настоятельно рекомендуется добавить проверку сертификата.См .: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

, который можно отключить, добавив в код следующие строки:

import requests
import ssl
import urllib3
urllib3.disable_warnings()
resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

Надеюсь, это поможет!

...