сбой проверки сертификата: невозможно получить сертификат локального эмитента - PullRequest
0 голосов
/ 14 октября 2018

Я пытаюсь получить данные из Интернета, используя python.Я импортировал для него пакет urllib.request, но во время выполнения получаю ошибку:

certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)

Когда я изменил URL-адрес на «http» - я могу получить данные.Но, я полагаю, это позволяет избежать проверки SSL-сертификата.

Поэтому я проверил в Интернете и нашел одно решение: Выполнить /Applications/Python\ 3.7/Install\ Certificates.command

Это решило мою проблему.Но у меня нет знаний по SSL и тому подобное.Можете ли вы помочь мне понять, что на самом деле было сделано для решения моей проблемы.

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

Спасибо!

Примечание. Я действительно прошел по ссылке - openssl, Python запрашивает ошибку: «сбой проверки сертификата»

Мой вопрос отличается от приведенного в ссылке, потому что я хочу знать, что на самом деле происходит, когда я устанавливаю certifi пакет или запускаю Install\ Certificates.command, чтобы исправить ошибку.У меня плохое понимание ценных бумаг.

1 Ответ

0 голосов
/ 08 мая 2019

Я столкнулся с той же проблемой в OSX, в то время как мой код был абсолютно нормальным в Linux, и вы дали ответ на свой вопрос!

После проверки файла, на который вы указали /Applications/Python 3.7/Install Certificates.command, оказалось, что эта команда заменяет корневые сертификаты установки Python по умолчанию на сертификаты, отправленные через пакет certifi.

certifi - это набор корневых сертификатов.Каждый сертификат SSL опирается на цепочку доверия: вы доверяете одному конкретному сертификату, потому что доверяете родителю этого сертификата, которому вы доверяете родителю и т. Д. В какой-то момент нет «родителя», а это «корневые» сертификаты.Для них не существует другого решения, кроме объединения обычно доверенных корневых сертификатов (обычно таких крупных доверенных компаний, как, например, «DigiCert»).

Вы можете, например, увидеть корневые сертификаты в настройках безопасности браузера (например, дляFirefox-> Настройки-> Конфиденциальность и безопасность-> Просмотр сертификатов-> Полномочия).

Возвращаясь к первоначальной проблеме, и перед запуском файла .command выполнение этого возвращает мне пустой список начистая установка:

import os
import ssl                                        
openssl_dir, openssl_cafile = os.path.split(      
    ssl.get_default_verify_paths().openssl_cafile)
# no content in this folder
os.listdir(openssl_dir)
# non existent file
print(os.path.exists(openssl_cafile))

Это означает, что не существует центра сертификации по умолчанию для установки Python в OSX.Возможное значение по умолчанию в точности совпадает с тем, которое предоставляется пакетом certifi.

После этого вы можете просто создать контекст SSL с соответствующим значением по умолчанию, как показано ниже (certifi.where() указывает местоположение центра сертификации):

import platform
# ...

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = True
ssl_context.load_default_certs()

if platform.system().lower() == 'darwin':
    import certifi
    ssl_context.load_verify_locations(
        cafile=os.path.relpath(certifi.where()),
        capath=None,
        cadata=None)

и сделайте запрос к url от python так:

import urllib
# previous context
https_handler = urllib.request.HTTPSHandler(context=ssl_context)

opener = urllib.request.build_opener(https_handler)
ret = opener.open(url, timeout=2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...