ошибка urllib и "SSL: ошибка проверки сертификата"

Я получаю следующую ошибку:

Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in        __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in  run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>

это код, который вызывает эту ошибку:

if input.startswith("!web"):
    input = input.replace("!web ", "")      
    url = "https://domainsearch.p.mashape.com/index.php?name=" + input
    req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
    info = urllib2.urlopen(req).read()
    Message.Chat.SendMessage ("" + info)

API, который я использую, требует, чтобы я использовал HTTPS. Как я могу обойти проверку?

24 ответов


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

будьте осторожны с этим, как указано в разделе 17.3.7.2.1

при вызове конструктора SSLContext напрямую, CERT_NONE является значением по умолчанию. Поскольку он не аутентифицирует другой одноранговый узел, он может быть небезопасным, особенно в клиентском режиме, где большую часть времени вы например, чтобы убедиться в подлинности сервера, с которым вы разговариваете. Поэтому в клиентском режиме настоятельно рекомендуется использовать CERT_REQUIRED.

но если вы просто хотите, чтобы он работал сейчас по какой-то другой причине, вы можете сделать следующее, вам придется import ssl а также:

input = input.replace("!web ", "")      
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)  # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)

Это должно обойти вашу проблему, но вы на самом деле не решаете ни одну из проблем, но вы не увидите [SSL: CERTIFICATE_VERIFY_FAILED] потому что теперь вы не проверяете сертификат!

для добавьте к вышесказанному, если вы хотите узнать больше о том, почему вы видите эти проблемы, вы захотите взглянуть на PEP 476.

этот ОПТОСОЗ предлагает включить проверку подписей сертификата X509, а также проверку имени хоста для HTTP-клиентов Python по умолчанию, при условии отказа на основе каждого вызова. Это изменение будет применено к Python 2.7, Python 3.4 и Python 3.5.

есть советуют отказаться, который не непохоже на мой совет выше:

import ssl

# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)

Он также имеет рекомендуется через monkeypatching который вы не часто видите в python:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

который переопределяет функцию по умолчанию для создания контекста с помощью функции для создания непроверенного контекста.

если вы хотите прочитать статью о том, почему не проверять сертификаты плохо в программном обеспечении вы можете найти его здесь!


это не решение вашей конкретной проблемы, но я помещаю его здесь, потому что этот поток является лучшим результатом Google для "SSL: CERTIFICATE_VERIFY_FAILED", и это приводит меня к погоне за диким гусем.

если вы установили Python 3.6 на OSX и получаете ошибку "SSL: CERTIFICATE_VERIFY_FAILED" при попытке подключиться к сайту https://, это, вероятно, потому, что Python 3.6 на OSX вообще не имеет сертификатов и не может проверить любые SSL-соединения. Это изменение 3.6 на OSX, и требует шага после установки, который устанавливает сертификаты. Это задокументировано в ReadMe, который вы должны найти в /Applications/Python\ 3.6/ReadMe.rtf

ReadMe заставит вас запустить этот скрипт после установки, который просто устанавливает certifi: /Applications/Python\ 3.6/Install\ Certificates.command

примечания к выпуску имеют дополнительную информацию:https://www.python.org/downloads/release/python-360/


чтобы расширить ответ Крейга Гленни (извините, недостаточно репутации, чтобы прокомментировать):

в Python 3.6.1 на MacOs Sierra

ввод этого в терминал bash решил проблему:

pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command

В Windows Python не смотрит на системный сертификат, он использует свой собственный, расположенный по адресу ?\lib\site-packages\certifi\cacert.pem.

решение проблемы:

  1. загрузите сертификат проверки домена как *.crt или * PEM файл
  2. открыть файл в редакторе и скопируйте его содержимое в буфер обмена
  3. найти cacert.pem местоположение: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
  4. редактировать cacert.pem file и вставьте сертификат проверки домена в конце файл.
  5. сохраните файл и наслаждайтесь запросы!

вы можете попробовать добавить это в переменные среды:

PYTHONHTTPSVERIFY=0 

обратите внимание, что это приведет к отключению все проверка HTTP так немного кувалды подход, однако, если проверка не требуется, это может быть эффективным решением.


мое решение для Mac OS X:

1) обновление до Python 3.6.5 с помощью собственного приложения Python installer, загруженного с официального сайта языка Pythonhttps://www.python.org/downloads/

Я обнаружил, что этот установщик заботится об обновлении ссылок и символических ссылок для нового Python намного лучше, чем homebrew.

2) Установите новый сертификат, используя "./установить сертификат.команда", которая находится в обновленном Python 3.6 каталог

> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"

import requests
requests.packages.urllib3.disable_warnings()

import ssl

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

Взято отсюда https://gist.github.com/michaelrice/a6794a017e349fc65d01


Как я написал в комментарии, эта проблема, вероятно, связана с это так ответ.

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

Вы можете попытаться получить недостающие сертификат Verisign Class 3 Публичный Первичный Центр Сертификации а затем используйте согласно документация Python:

urllib2.urlopen(req, cafile="verisign.pem")

у меня была аналогичная проблема, хотя я использовал urllib.request.urlopen на в Python 3.4, 3.5 и 3.6. (Это часть эквивалента Python 3 urllib2, в примечании во главе Python 2 в urllib2 страница документация.)

моим решением было pip install certifi установить certifi, который имеет:

... тщательно кураторская коллекция корневых сертификатов для проверки надежности SSL сертификаты при проверке подлинности узлов TLS.

затем, в моем коде, где я ранее просто имел:

import urllib.request as urlrq
resp = urlrq.urlopen('https://foo.com/bar/baz.html')

я изменил его на:

import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://foo.com/bar/baz.html', cafile=certifi.where())

если я читаю urllib2.urlopen документация правильно, он также имеет


на Python 3.4+ on Centos 6/7, Fedora, просто установите доверенный CA таким образом:

  1. скопируйте CA.crt to /etc/pki/ca-trust/source/anchors/
  2. update-ca-trust force-enable
  3. update-ca-trust extract

Я опускаю голову в полу-стыде, так как у меня была та же проблема, за исключением того, что в моем случае URL, который я нажимал, был действителен, сертификат был действителен. Что не было действительным, так это моя связь с сетью. Мне не удалось добавить данные прокси-сервера в браузер (т. е. в этом случае). Это остановило процесс проверки.
Добавлено в детали прокси, и мой python был тогда очень доволен .


как и вы, я использую python 2.7 на моем старом iMac (OS X 10.6.8), я тоже столкнулся с проблемой, используя urllib2.urlopen:

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]

мои программы работали нормально без проблем SSL-сертификата и suddently (после загрузки программ), они разбились с этой ошибкой SSL.

проблема заключалась в используемой версии python:

  1. нет проблем с https://www.python.org/downloads и python-2.7.9-macosx10.6.pkg

  2. проблема с тем, который установлен инструмент доморощенного : "brew install python", версия, расположенная в /usr/local/bin.

глава, называется Certificate verification and OpenSSL [CHANGED for Python 2.7.9], в /Applications/Python 2.7/ReadMe.rtf объясняет проблему со многими деталями.

Итак, проверьте, загрузите и поместите в свой путь правильную версию python.


попробовать

pip install --trusted-host pypi.python.org packagename

Это сработало для меня.


Я удивлен, что все эти инструкции не решили мою проблему. Тем не менее, диагностика правильная (кстати, я использую Mac и Python3.6.1). Итак, подводя итог правильной части:

  • на Mac Apple сбрасывает OpenSSL
  • Python теперь использует собственный набор корневого сертификата CA
  • бинарная установка Python при условии, сценарий для установки корневого сертификата CA Python потребности ("/приложения / Python 3.6 / Install Сертификаты.команда")
  • Read " / Приложения / Python 3.6 / ReadMe.rtf " для деталей

для меня скрипт не работает, и все эти установки certifi и openssl также не удалось исправить. Может быть, потому, что у меня есть несколько установок python 2 и 3, а также много virtualenv. В конце концов, мне нужно исправить его вручную.

pip install certifi   # for your virtualenv
mkdir -p /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl
cp -a <your virtualenv>/site-package/certifi/cacert.pem \
  /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem

Если это все еще не удается. Затем повторно установите OpenSSL.

port install openssl

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

Я использую MacPorts, и то, что я изначально считал проблемой Python, на самом деле было проблемой MacPorts: он не устанавливает корневой сертификат с его установкой openssl. Решение port install curl-ca-bundle, Как указано в этот блог.


посмотри

/ Приложения / Python 3.6 / Установить Сертификаты.команда

вы также можете перейти к приложениям и нажать на сертификаты.команда


Если ваш на vCenter 6, Вы должны вместо этого добавить сертификат центра сертификации vmware vCenter в список доверенных ЦС вашей ОС. Чтобы загрузить Ваш сертификат, сделайте следующее

  1. откройте веб-браузер.
  2. перейдите к https://
  3. в правом нижнем углу щелкните ссылку Загрузить доверенный корневой CA

В Fedora

  1. распакуйте и измените расширение .От 0 до .cer
  2. скопируйте его в / etc/pki/ca-trust/источник/якоря/
  3. выполните команду update-ca-trust.

ссылки:

  1. https://virtualizationreview.com/articles/2015/04/02/install-root-self-signed-certificate-vcenter-6.aspx?m=1
  2. http://forums.fedoraforum.org/showthread.php?t=293856

питон 2.7.12 (по умолчанию, 29 июля 2016, 15:26:22) Исправлена проблема. Эта информация может помочь кому-то еще.


установка шагов для nltk (у меня был python3 (3.6.2), установленный уже в MAC OS X

sudo easy_install pip

использовать игнорировать установленную опцию, чтобы игнорировать удаление предыдущей версии шести, иначе, это дает ошибку при удалении и не фильм вперед

sudo pip3 install -U nltk --ignore-installed six

Проверьте установку pip и python, используйте версии "3"

which python python2 python3
which pip pip2 pip3

проверьте, установлен ли NLTK

python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']

установите сертификат SSL перед установкой книги примеров, иначе мы будем ошибка сертификата при установке примеров

/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book

который успешно завершил установку nltk и nltk_ata для примеров книг


установка PyOpenSSL С помощью pip работал для меня (без преобразования в PEM):

pip install PyOpenSSL

Я решил эту проблему, закрыв Fiddler (прокси-сервер отладки HTTP), проверьте, включен ли прокси-сервер, и повторите попытку.


Python 2.7 на Amazon EC2 с centOS 7

мне пришлось установить переменную env SSL_CERT_DIR для ca-bundle который был расположен в /etc/ssl/certs/ca-bundle.crt


в python 2.7 добавление сведений доверенного корневого ЦС в конце файла C:\Python27\lib\site-packages\certifi\cacert - ... Пем помог!--1-->

после этого я запустил (используя права администратора) типун установки --доверенный хост pypi.python.org --надежного хозяина pypi.org --надежного хозяина имя_пакета files.pythonhosted.org


ln -s /usr/local/share/certs/ca-root-nss.crt /etc/ssl/cert.pem

(FreeBSD 10.1)