Решение ошибки в Python: 'Certificate verify failed'
Быстрый ответ
Для решения проблем с SSL-сертификатом в Python, используя библиотеку requests
, укажите параметр verify
со ссылкой на ваш сертификат:
requests.get('https://example.com', verify='/path/to/cert.pem')
Если требуется отладка, временно можно отключить проверку (это небезопасно и не подходит для продакшена):
requests.get('https://example.com', verify=False)
Если у Python нет доступа к списку доверенных сертификатов, установка пакета certifi
может помочь:
import requests
import certifi
response = requests.get('https://example.com', verify=certifi.where())
Для пользователей Mac может оказаться полезной команда "Install Certificates.command":
open /Applications/Python\ 3.x/Install\ Certificates.command
Ниже представлены более подробные руководства и подходы.
Восстановление доверительной цепочки
Связь Python с системными SSL-сертификатами
Создайте символическую ссылку, чтобы связать системные SSL-сертификаты с Python:
ln -s /etc/ssl/certs/ca-certificates.crt /path/to/python/site-packages/certifi/cacert.pem
Обновление SSL-сертификатов
Обновите сертификаты с помощью "Install Certificates.command" на MacOS или через пакетный менеджер в Linux:
sudo apt-get install --reinstall ca-certificates
Создание безопасного контекста с помощью модуля ssl Python
Настройте SSL-контекст, указав ссылку на файл корневых сертификатов:
import ssl
import certifi
import urllib.request
context = ssl.create_default_context(cafile=certifi.where())
response = urllib.request.urlopen("https://example.com", context=context)
Работа с SSL-сертификатами на MacOS
В MacOS сертификаты расположены в каталоге /etc/ssl/
, однако Python может не использовать системное хранилище сертификатов. Для проведения SSL-проверки необходимо настроить доступ к правильному хранилищу.
В Python 3.6 и более новых версиях для MacOS уже встроен собственный OpenSSL, который может не содержать все необходимые корневые сертификаты. Отсюда и возникают проблемы с доверием.
Обеспечение безопасности HTTPS-запросов
Правильно настроенный SSL-контекст имеет решающее значение для безопасных HTTPS-запросов:
import ssl
import urllib.request
context = ssl._create_unverified_context() # Только для разработки; не используйте в продакшн-среде
response = urllib.request.urlopen("https://example.com", context=context)
Особенности безопасных сертификатов
Понимание принципов работы SSL-сертификатов помогает решить связанные с ними проблемы. Использование certifi
позволяет поддерживать актуальное хранилище корневых сертификатов.
При возникновении ошибки, о том что Python не может найти локальный корневой сертификат, обновите хранилище сертификатов на MacOS или настройте правильный SSL-контекст.
Принцип работы корневых Удостоверяющих Центров
Сервер идентифицирует вас, опираясь на цепочку доверия до корневого УЦ. Если УЦ, выдавший сертификат вашему серверу, отсутствует в списке доверенных, произойдёт ошибка, если только вы явно не укажете нужный сертификат.
Визуализация
Сравним проверку SSL-сертификата со службой безопасности аэропорта:
✈️ Сотрудник службы безопасности: "Предъявите ваши документы."
👤 Вы: *предъявляете документы*
👮 Сотрудник: "Подождите, нужно проверить их подлинность..."
В случае ошибки с сертификатом:
👮 Сотрудник: "Я не могу подтвердить подлинность этих документов."
👤 Вы: *доступ запрещён* 🚫
Ключ к решению: Программа (аэропорт) откажет в доступе, если не сможет установить доверие к эмитенту (стране, выпустившей паспорт).
Решение: Настройте программу на распознавание эмитента, обновив или сконфигурировав хранилище (через certifi
, OpenSSL и т. д.).
Подробное изучение решения
Ситуация: Python не может найти УЦ
Если Python не может найти необходимый УЦ, выполните команду "Install Certificates.command" или используйте конкретный сертификат УЦ:
# На MacOS выполните эту команду
open /Applications/Python\ 3.x/Install\ Certificates.command
# или укажите путь к файлу с сертификатами УЦ в коде
requests.get('https://example.com', verify='/path/to/ca-bundle.crt')
Ситуация: Приватные или настроенные УЦ
Для сертификатов приватных или настроенных УЦ вам потребуется добавить их в хранилище сертификатов Python:
requests.get('https://example.com', verify='/path/to/custom-ca.pem')
Ситуация: Кросс-платформенная совместимость
Для обеспечения работы на разных платформах настройте Python на использование certifi
:
requests.get('https://example.com', verify=certifi.where())
Полезные материалы
- Документация Python-запросов 2.31.0 — Расширенное использование — модуль Requests в Python описывает процесс проверки SSL-сертификата.
- Удостоверяющий центр OpenSSL — Jamie Nguyen — подробное руководство по созданию собственного УЦ OpenSSL.
- Python SSL Сертификаты – Stack Overflow — обсуждения сообщества о проблемах с SSL-сертификатами в Python.
- ssl — модуль Python для работы с TLS/SSL — официальная документация модуля SSL Python.
- Let's Encrypt — сервис, предоставляющий бесплатные SSL/TLS-сертификаты для обеспечения безопасности веб-среды.
- Как исправить ошибку Python SSL CERTIFICATE_VERIFY_FAILED — пошаговое руководство по исправлению ошибки Python SSL CERTIFICATE_VERIFY_FAILED.
- certifi | PyPI — пакет Python, обеспечивающий доступ к актуальному списку Корневых Сертификатов Mozilla.