it-swarm.com.de

urllib und "SSL: CERTIFICATE_VERIFY_FAILED" Fehler

Ich erhalte folgende Fehlermeldung:

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)>

Dies ist der Code, der diesen Fehler verursacht:

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)

Die von mir verwendete API erfordert die Verwendung von HTTPS. Wie kann ich die Überprüfung umgehen?

192
user3724476

Wenn Sie nur die Überprüfung umgehen möchten, können Sie einen neuen SSLContext erstellen. Standardmäßig verwenden neu erstellte Kontexte CERT_NONE .

Seien Sie vorsichtig damit, wie in Abschnitt 17.3.7.2.1 angegeben.

Beim direkten Aufruf des SSLContext-Konstruktors ist CERT_NONE die Standardeinstellung. Da der andere Peer nicht authentifiziert wird, kann er unsicher sein, insbesondere im Client-Modus, in dem Sie meistens die Authentizität des Servers sicherstellen möchten, mit dem Sie sprechen. Im Client-Modus wird daher dringend empfohlen, CERT_REQUIRED zu verwenden. 

Wenn Sie jedoch möchten, dass es jetzt aus einem anderen Grund funktioniert, können Sie Folgendes tun: Sie müssen auch 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()  # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)

Dies sollte Ihr Problem lösen, aber Sie lösen das Problem nicht wirklich, aber Sie werden den [SSL: CERTIFICATE_VERIFY_FAILED] nicht sehen, da Sie das Zertifikat jetzt nicht überprüfen!

Wenn Sie mehr darüber erfahren möchten, warum Sie diese Probleme sehen, sollten Sie einen Blick auf PEP 476 werfen.

In diesem PEP wird vorgeschlagen, die Überprüfung von X509-Zertifikatsignaturen sowie die Überprüfung des Hostnamens für HTTP-Clients von Python standardmäßig zu aktivieren, wobei die Abmeldung auf Anrufbasis deaktiviert werden kann. Diese Änderung wird auf Python 2.7, Python 3.4 und Python 3.5 angewendet. 

Es gibt ein empfohlenes Opt-Out, das meinem oben genannten Rat nicht unähnlich ist:

import ssl

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

Es enthält auch eine sehr entmutigte Option über monkeypatching , die Sie in Python nicht oft sehen:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

Die Standardfunktion für die Kontexterstellung wird mit der Funktion zum Erstellen eines ungeprüften Kontexts überschrieben.

Bitte beachten Sie dabei wie im PEP angegeben:

Diese Anleitung richtet sich in erster Linie an Systemadministratoren, die neuere Versionen von Python übernehmen möchten, die dieses PEP in älteren Umgebungen implementieren, in denen noch keine Zertifikatsüberprüfung für HTTPS-Verbindungen unterstützt wird. Beispielsweise kann ein Administrator die Option ablehnen, indem er den oben genannten Monkeypatch zu sitecustomize.py in seiner Standard-Betriebsumgebung für Python hinzufügt. Anwendungen und Bibliotheken MÜSSEN diese Änderungsprozesse NICHT durchführen (außer vielleicht als Reaktion auf eine vom Systemadministrator gesteuerte Konfigurationseinstellung). 

Wenn Sie ein Papier darüber lesen möchten, warum das Nicht-Validieren von Zertifikaten in der Software schlecht ist finden Sie es hier !

217
Noelkd
246
Craig Glennie

Um auf Craig Glennies Antwort einzugehen (tut mir leid, nicht genug Ruf, um einen Kommentar abzugeben)

in Python 3.6.1 auf MacOs Sierra

Die Eingabe in das Bash-Terminal löste das Problem:

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

Unter Windows betrachtet Python das Systemzertifikat nicht, es verwendet ein eigenes Zertifikat unter ?\lib\site-packages\certifi\cacert.pem.

Die Lösung für Ihr Problem: 

  1. laden Sie das Domain-Validierungszertifikat als * .crt- oder * pem-Datei herunter
  2. Öffnen Sie die Datei im Editor und kopieren Sie den Inhalt in die Zwischenablage
  3. finden Sie Ihren cacert.pem-Standort: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
  4. bearbeiten Sie die Datei cacert.pem und fügen Sie das Domänenvalidierungszertifikat am Ende der Datei ein.
  5. Speichern Sie die Datei und freuen Sie sich auf Anfragen!
25
Bruno Gabuzomeu

Meine Lösung für Mac OS X:

1) Führen Sie ein Upgrade auf Python 3.6.5 durch. Verwenden Sie dazu das native Python-Installationsprogramm, das von der offiziellen Python-Website heruntergeladen wurde. Https://www.python.org/downloads/

Ich habe festgestellt, dass dieser Installer die Links und Symlinks für den neuen Python viel besser aktualisiert als Homebrew. 

2) Installieren Sie ein neues Zertifikat mit "./Install Certificates.command" im aktualisierten Python 3.6-Verzeichnis 

> cd "/Applications/Python 3.6/"
> Sudo "./Install Certificates.command"
22
Claude COULOMBE

Sie könnten versuchen, dies Ihren Umgebungsvariablen hinzuzufügen:

PYTHONHTTPSVERIFY=0 

Beachten Sie, dass dadurch die Überprüfung von all HTTP deaktiviert wird. Dies ist ein bisschen ein Vorschlag für einen Vorschlaghammer. Wenn jedoch keine Überprüfung erforderlich ist, kann dies eine effektive Lösung sein.

22
Chris Halcrow

Ich hatte ein ähnliches Problem, obwohl ich urllib.request.urlopen in Python 3.4, 3.5 und 3.6 verwendete. (Dies ist ein Teil des Python 3-Äquivalents von urllib2, entsprechend der Anmerkung am Anfang von Python 2s urllib2-Dokumentationsseite .

Meine Lösung war pip install certifi, um certifi zu installieren, das Folgendes hat:

... eine sorgfältig kuratierte Sammlung von Stammzertifikaten zur Überprüfung der Vertrauenswürdigkeit von SSL-Zertifikaten und zur Überprüfung der Identität von TLS-Hosts.

Dann in meinem Code, wo ich zuvor nur hatte:

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

Ich habe es überarbeitet an:

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

Wenn ich die urllib2.urlopen Dokumentation richtig gelesen habe, hat sie auch ein cafile-Argument. urllib2.urlopen([...], certifi.where()) könnte also auch für Python 2.7 funktionieren.

12
hBy2Py
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

Aus hier genommen https://Gist.github.com/michaelrice/a6794a017e349fc65d01

11
Prostak

Wie ich in einem Kommentar geschrieben habe, hängt dieses Problem wahrscheinlich mit dieser SO Antwort zusammen. 

Kurz gesagt: Es gibt mehrere Möglichkeiten, das Zertifikat zu überprüfen. Die von OpenSSL verwendete Überprüfung ist nicht kompatibel mit den vertrauenswürdigen Stammzertifikaten, die Sie auf Ihrem System haben. OpenSSL wird von Python verwendet.

Sie könnten versuchen, das fehlende Zertifikat für Verisign Class 3 Public Primary Certification Authority zu erhalten und dann die Option cafile gemäß der Python-Dokumentation zu verwenden :

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

Für Python 3.4+ on Centos 6/7, Fedora , installieren Sie die vertrauenswürdige Zertifizierungsstelle folgendermaßen:

  1. Kopieren Sie die CA.crt nach /etc/pki/ca-trust/source/anchors/
  2. update-ca-trust force-enable
  3. update-ca-trust extract
4
Cherif KAOUA

Ich muss eine weitere Antwort hinzufügen, da ich, genau wie Craig Glennie, wegen der vielen Posts, die sich auf dieses Problem im Web beziehen, auf eine wilde Verfolgungsjagd gegangen ist.

Ich verwende MacPorts, und was ich ursprünglich für ein Python-Problem hielt, war in der Tat ein MacPorts-Problem: Es installiert kein Stammzertifikat bei der Installation von openssl. Die Lösung ist port install curl-ca-bundle, wie in diesem Blogbeitrag erwähnt.

3
corwin.amber

Ich hänge meinen Kopf halbscham, da ich das gleiche Problem hatte, außer dass in meinem Fall die URL, die ich traf, gültig war, das Zertifikat gültig war. Was nicht gültig war, war meine Verbindung ins Internet. Es war nicht möglich, Proxy-Details in den Browser (in diesem Fall IE) einzufügen. Dies hat dazu geführt, dass der Überprüfungsprozess nicht mehr ordnungsgemäß ausgeführt wurde.
In den Proxy-Details hinzugefügt und mein Python war dann sehr glücklich.

2
Ads

Ich bin überrascht, dass alle diese Anweisungen mein Problem nicht gelöst haben. Trotzdem ist die Diagnose korrekt (BTW, ich verwende Mac und Python3.6.1). Um den richtigen Teil zusammenzufassen:

  • Auf dem Mac lässt Apple OpenSSL fallen
  • Python verwendet jetzt seinen eigenen CA-Stammzertifikatsatz
  • Bei der binären Python-Installation wurde ein Skript zum Installieren des CA-Stammzertifikats bereitgestellt, das Python benötigt ("/ Applications/Python 3.6/Certificates.command installieren")
  • Lesen Sie "/ Applications/Python 3.6/ReadMe.rtf" für Details

Für mich funktioniert das Skript nicht und auch die Installation von certifi und openssl konnte nicht korrigiert werden. Vielleicht, weil ich mehrere Python 2- und 3-Installationen sowie viele Virtualenv-Installationen habe. Am Ende muss ich es von Hand reparieren.

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

Wenn das immer noch fehlschlägt. Dann installieren/installieren Sie ebenfalls OpenSSL.

port install openssl
2
berniey

Wie Sie benutze ich Python 2.7 auf meinem alten iMac (OS X 10.6.8). Ich habe auch das Problem mit urllib2.urlopen getroffen: 

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]

Meine Programme liefen einwandfrei ohne SSL-Zertifikatprobleme und plötzlich (nach dem Herunterladen von Programmen) stürzten sie mit diesem SSL-Fehler ab.

Das Problem war die verwendete Python-Version:

  1. Kein Problem mit https://www.python.org/downloads und python-2.7.9-macosx10.6.pkg

  2. problem mit einem von Homebrew-Tool installierten : "brew install python", Version in/usr/local/bin.

Ein Kapitel mit dem Namen Certificate verification and OpenSSL [CHANGED for Python 2.7.9] in /Applications/Python 2.7/ReadMe.rtf erläutert das Problem mit vielen Details.

Überprüfen Sie also, laden Sie die richtige Version von Python herunter, und laden Sie sie in PATH ein.

2

Versuchen

pip install --trusted-Host pypi.python.org Paketname

Es hat für mich funktioniert. 

1
user3603105

Schaut mal rein

/ Applications/Python 3.6/Certificates.command installieren

Sie können auch zu Anwendungen gehen und auf Zertifikate.Befehl klicken

1
Danielle Cohen

Python 2.7.12 (Standard, 29. Juli 2016, 15:26:22) behebt das erwähnte Problem. Diese Informationen können jemand anderem helfen.

1
caot

Für jeden, der mechanize verwendet, dem diese Frage begegnet, können Sie dieselbe Technik auf eine mechanisierte Browser-Instanz anwenden:

br = mechanize.Browser()
context = ssl._create_unverified_context()
br.set_ca_data(context=context)
0
Kirkman14

Wenn Sie sich in vCenter 6 befinden, sollten Sie stattdessen das Zertifikat der Zertifizierungsstelle für vmware-Zertifizierungsstellen Ihres vCenter zur Liste der vertrauenswürdigen Zertifizierungsstellen Ihres Betriebssystems hinzufügen. So laden Sie Ihr Zertifikat herunter:

  1. Öffnen Sie Ihren Webbrowser.
  2. Navigieren Sie zu https: //
  3. Klicken Sie in der rechten unteren Ecke auf den Link Trusted Root CA herunterladen 

Auf Fedora 

  1. entpacken und ändern Sie die Erweiterung von .0 in .cer 
  2. Kopieren Sie es nach/etc/pki/ca-trust/source/anchors /
  3. führen Sie den Befehl update-ca-trust aus.

Links:

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

Bereits viele Antworten hier, aber wir sind in einem ganz bestimmten Fall darauf gestoßen und haben viel Zeit damit verbracht, Nachforschungen anzustellen, also noch eine hinzuzufügen. Wir haben es im folgenden Fall gesehen:

  • In einem Debian-Stretch-Slim-Docker-Container
  • Standard Python 3.5.3 easy_install3
  • Für LetsEncrypt-Zertifikate, die mit cert-manager in unserem Kubernetes-Cluster registriert wurden

Sowohl pip3 als auch openssl konnten das Zertifikat verifizieren, und easy_install3 konnte andere LetsEncrypt-Zertifikate erfolgreich verifizieren.

Die Problemumgehung bestand darin, das neueste Python (3.7.3 zu der Zeit) aus dem Quellcode zu erstellen. Die Anweisungen hier sind ausführlich und leicht zu befolgen.

0
aschmied

In meinem Fall habe ich diesen Fehler erhalten, weil die Versionen requests und urllib3 nicht kompatibel waren. Dies führte bei der Installation zu folgendem Fehler:

ERROR: requests 2.21.0 has requirement urllib3<1.25,>=1.21.1, but you'll have urllib3 1.25 which is incompatible.
pip install 'urllib3<1.25' --force-reinstall

hat den Trick gemacht.

0
fabio.sang

In Python 2.7 fügen Sie am Ende in der Datei C:\Python27\lib\site-packages\certifi\cacert.pem das Hinzufügen vertrauenswürdiger Stammzertifizierungsstellen hinzu

danach habe ich ausgeführt (mit Administratorrechten) pip install --trusted-Host pypi.python.org --trusted-Host pypi.org --trusted-Host files.pythonhosted.org Paketname

0
MD5

Für Linux Python3.6 hat dies bei mir funktioniert.

von der Kommandozeile aus installieren Sie pyopenssl und certifi

Sudo pip3 install -U pyopenssl
Sudo pip3 install certifi

und fügte in meinem Python3-Skript verify = '/ usr/lib/python3.6/site-packages/certifi/cacert.pem' folgendermaßen hinzu:

import requests
from requests.auth import HTTPBasicAuth
import certifi

auth = HTTPBasicAuth('username', 'password')
body = {}

r = requests.post(url='https://your_url.com', data=body, auth=auth, verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem')
0
Joe Jadamec

Python 2.7 auf Amazon EC2 mit centOS 7

Ich musste die env-Variable SSL_CERT_DIR so einstellen, dass sie auf meinen ca-bundle verweist, der sich bei /etc/ssl/certs/ca-bundle.crt befand.

0
Brian McCall

Ich habe das über hier gefunden

Ich habe diese Lösung gefunden, füge diesen Code am Anfang deiner Quelldatei ein:

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

Dieser Code macht die Überprüfung rückgängig, sodass die SSL-Zertifizierung nicht überprüft wird.

installationsschritte für nltk (Ich hatte Python3 (3.6.2) bereits in MAC OS X installiert

Sudo easy_install pip

verwenden Sie die Option zum Ignorieren der installierten Option, um die Deinstallation der vorherigen Version von sechs zu ignorieren. Andernfalls wird bei der Deinstallation ein Fehler angezeigt

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

Überprüfen Sie die Installation von Pip und Python, verwenden Sie die '3'-Versionen

which python python2 python3
which pip pip2 pip3

Prüfen Sie, ob NLTK installiert ist

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

Installieren Sie das SSL-Zertifikat vor der Installation des Beispielbuchs. Andernfalls werden bei der Installation der Beispiele Fehler gemeldet

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

Damit wurde die Installation von nltk und nltk_ata für Buchbeispiele erfolgreich abgeschlossen

0
Narasimha Sai

Lösung für Anaconda

Mein Setup ist Anaconda Python 3.7 unter MacOS mit einem Proxy. Die Wege sind unterschiedlich.

  • So erhalten Sie den Pfad richtig Zertifikate:
import ssl
ssl.get_default_verify_paths()

was auf meinem system produziert

Out[35]: DefaultVerifyPaths(cafile='/miniconda3/ssl/cert.pem', capath=None,
 openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/miniconda3/ssl/cert.pem',
 openssl_capath_env='SSL_CERT_DIR', openssl_capath='/miniconda3/ssl/certs')

Sobald Sie wissen, wohin das Zertifikat geht, verketten Sie das vom Proxy verwendete Zertifikat bis zum Ende dieser Datei.

Ich hatte conda bereits für die Arbeit mit meinem Proxy eingerichtet, indem ich Folgendes ausführte:

conda config --set ssl_verify <pathToYourFile>.crt

Wenn Sie sich nicht erinnern, wo sich Ihr Zertifikat befindet, finden Sie es in ~/.condarc:

ssl_verify: <pathToYourFile>.crt

Jetzt verketten sollte diese Datei bis zum Ende von /miniconda3/ssl/cert.pem und Requests funktionieren, und insbesondere sollten sklearn.datasets und ähnliche Tools funktionieren.

Weitere Vorsichtsmaßnahmen

Die anderen Lösungen haben nicht funktioniert, da sich das Anaconda-Setup geringfügig unterscheidet:

  • Der Pfad Applications/Python\ 3.X existiert einfach nicht.

  • Der von den Befehlen unten bereitgestellte Pfad ist derFALSCHEPfad

from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
0
Leo

Die Installation von PyOpenSSL mit pip hat für mich funktioniert (ohne in PEM zu konvertieren):

pip install PyOpenSSL
0
averma93

Ich hatte dieses Problem gelöst, indem Fiddler (ein HTTP-Debugging-Proxy) geschlossen wurde. Überprüfen Sie, ob ein Proxy aktiviert ist, und versuchen Sie es erneut. 

0
vperezb

Die Installation des Zertifikats auf dem Mac hat mein Problem gelöst:

pip install certifi
0
Snehal Parmar

Eine andere Anaconda Lösung. Ich habe CERTIFICATE_VERIFY_FAILED in meiner Python 2.7-Umgebung unter macOS erhalten. Es stellte sich heraus, dass die Conda-Pfade schlecht waren:

basisumgebung (3.7):

>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/usr/local/anaconda3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/ssl/certs')

2.7 Umgebung (Pfade existierten nicht!):

DefaultVerifyPaths(cafile='', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/envs/py27/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/envs/py27/ssl/certs')

Die Reparatur:

cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem
0
Peter Tseng