urllib en SSL: CERTIFICATE_VERIFY_FAILED Fout

Ik krijg de volgende foutmelding:

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

Dit is de code die deze fout veroorzaakt:

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)

Voor de API die ik gebruik, moet ik HTTPS gebruiken. Hoe kan ik de verificatie omzeilen?


Antwoord 1, autoriteit 100%

Als u alleenverificatie wilt omzeilen, kunt u een nieuwe SSLContext. Standaard gebruiken nieuw gemaakte contexten CERT_NONE.

Wees hier voorzichtig mee zoals vermeld in sectie 17.3.7.2.1

Als u de SSLContext-constructor rechtstreeks aanroept, is CERT_NONE de standaardinstelling. Omdat het de andere peer niet verifieert, kan het onveilig zijn, vooral in de clientmodus, waar je meestal de authenticiteit van de server waarmee je praat wilt verzekeren. Daarom wordt het ten zeerste aanbevolen om in clientmodus CERT_REQUIRED te gebruiken.

Maar als je om een ​​andere reden gewoon wilt dat het nu werkt, kun je het volgende doen, je moet ook 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)

Dit zou je probleem moeten omzeilen, maar je lost geen van de problemen echt op, maar je zult de [SSL: CERTIFICATE_VERIFY_FAILED]niet zien omdat je het certificaat nu niet verifieert!

Als aanvulling op het bovenstaande, als u meer wilt weten over waarom u deze problemen ziet, kunt u een kijkje nemen op PEP 476.

Deze PEP stelt voor om standaard verificatie van X509-certificaathandtekeningen in te schakelen, evenals hostnaamverificatie voor Python’s HTTP-clients, afhankelijk van de opt-out per oproep. Deze wijziging wordt toegepast op Python 2.7, Python 3.4 en Python 3.5.

Er is een geadviseerde opt-out die niet verschilt van mijn advies hierboven:

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

Het bevat ook een zeer ontmoedigdeoptie via monkeypatchingdie u zie je niet vaak in python:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

Die de standaardfunctie voor het maken van contexten overschrijft met de functie om een ​​niet-geverifieerde context te maken.

Let hierbij op zoals vermeld in het PEP:

Deze richtlijnen zijn voornamelijk bedoeld voor systeembeheerders die nieuwere versies van Python willen gebruiken die deze PEP implementeren in legacy-omgevingen die nog geen certificaatverificatie op HTTPS-verbindingen ondersteunen. Een beheerder kan zich bijvoorbeeld afmelden door de apenpatch hierboven toe te voegen aan sitecustomize.py in hun Standard Operating Environment voor Python. Applicaties en bibliotheken MOETEN dit wijzigingsproces NIET breed maken(behalve misschien als reactie op een door de systeembeheerder gecontroleerde configuratie-instelling).

Als je een paper wilt lezen over waarom het niet valideren van certificaten slecht is in software je kunt het hier vinden!


Antwoord 2, autoriteit 95%

Dit is geen oplossing voor uw specifieke probleem, maar ik plaats het hier omdat deze thread het beste Google-resultaat is voor “SSL: CERTIFICATE_VERIFY_FAILED”, en het leidde me op een wilde gansjacht.

Als je Python 3.6 op OSX hebt geïnstalleerd en de foutmelding “SSL: CERTIFICATE_VERIFY_FAILED” krijgt wanneer je probeert verbinding te maken met een https://-site, komt dat waarschijnlijk omdat Python 3.6 op OSX helemaal geen certificaten heeft en dat ook niet kan valideer eventuele SSL-verbindingen. Dit is een wijziging voor 3.6 op OSX en vereist een post-installatiestap, die het pakket certifimet certificaten installeert. Dit is gedocumenteerd in het bestand ReadMe.rtf, die je kunt vinden op /Applications/Python\ 3.6/ReadMe.rtf(zie ook het bestand Conclusion.rtfen het script build-installer.pydie het macOS-installatieprogramma genereert).

De ReadMe laat u het script na de installatie uitvoeren op /Applications/Python\ 3.6/Install\ Certificates.command(de bron is install_certificates.command), die:

Release-opmerkingen bevatten wat meer informatie: https://www.python.org/ downloads/release/python-360/

Over nieuwere versies van Python is hier meer documentatie over:


Antwoord 3, autoriteit 24%

Om het antwoord van Craig Glennie uit te breiden:

in Python 3.6.1 op MacOs Sierra

Dit invoeren in de bash-terminal loste het probleem op:

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

Antwoord 4, autoriteit 15%

In Windows kijkt Python niet naar het systeemcertificaat, het gebruikt zijn eigen certificaat op ?\lib\site-packages\certifi\cacert.pem.

De oplossing voor uw probleem:

  1. download het domeinvalidatiecertificaat als *.crt- of *pem-bestand
  2. open het bestand in de editor en kopieer de inhoud naar het klembord
  3. vind uw cacert.pemlocatie: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
  4. bewerk het bestand cacert.pemen plak uw domeinvalidatiecertificaat aan het einde van het bestand.
  5. Sla het bestand op en geniet van verzoeken!

Antwoord 5, autoriteit 13%

Mijn oplossing voor Mac OS X:

1) Upgrade naar Python 3.6.5 met behulp van de native app Python-installatieprogramma gedownload van de officiële Python-taalwebsite https: //www.python.org/downloads/

Ik heb ontdekt dat dit installatieprogramma zorgt voor het updaten van de links en symbolische links voor de nieuwe Python een stuk beter dan homebrew.

2) Installeer een nieuw certificaat met “./Install Certificates.command” in de vernieuwde Python 3.6 directory

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

Antwoord 6, autoriteit 13%

Ik had een soortgelijk probleem, hoewel ik urllib.request.urlopengebruikte in Python 3.4, 3.5 en 3.6. (Dit is een deel van het Python 3-equivalent van urllib2, volgens de opmerking aan het begin van urllib2documentatiepagina.)

Mijn oplossing was om pip install certifite installeren om certifi, die heeft:

… een zorgvuldig samengestelde verzameling rootcertificaten om de betrouwbaarheid van SSL-certificaten te valideren en tegelijkertijd de identiteit van TLS-hosts te verifiëren.

Vervolgens, in mijn code waar ik eerder net had:

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

Ik heb het aangepast tot:

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

Als ik de urllib2.urlopenlees documentatiecorrect is, heeft het ook een cafile-argument. Dus urllib2.urlopen([...], certifi.where())werkt mogelijk ook voor Python 2.7.


UPDATE (01-01-2020):Vanaf Python 3.6, het cafile-argument voor urlopenis verouderd, waarbij het context-argument verondersteld wordt in plaats daarvan te specificeren. Ik vond het volgende even goed werken op 3.5 tot 3.8:

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

Antwoord 7, autoriteit 11%

Je zou kunnen proberen dit toe te voegen aan je omgevingsvariabelen:

PYTHONHTTPSVERIFY=0 

Houd er rekening mee dat hiermee alleHTTPS-verificatie wordt uitgeschakeld, dus het is een beetje een mokerbenadering, maar als verificatie niet vereist is, kan het een effectieve oplossing zijn.


Antwoord 8, autoriteit 4%

Ik had een soortgelijk probleem op een van mijn Linux-machines. Nieuwe certificaten genereren en een omgevingsvariabele exporteren die naar de map met certificaten wijst, loste het voor mij op:

$ sudo update-ca-certificates --fresh
$ export SSL_CERT_DIR=/etc/ssl/certs

Antwoord 9, autoriteit 4%

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

Vanaf hier genomen https://gist.github.com/michaelrice/a6794a017e349fc65d01


Antwoord 10, autoriteit 3%

Zoals ik in een opmerking heb geschreven, heeft dit probleem waarschijnlijk te maken met dit SO-antwoord.

Kortom: er zijn meerdere manieren om het certificaat te verifiëren. De verificatie die door OpenSSL wordt gebruikt, is niet compatibel met de vertrouwde rootcertificaten die u op uw systeem heeft. OpenSSL wordt gebruikt door Python.

U kunt proberen het ontbrekende certificaat voor Verisign Class 3 Public Primary Certification Authorityen gebruik vervolgens de optie cafilevolgens de Python-documentatie:

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

Antwoord 11, autoriteit 2%

$ cd $HOME
$ wget --quiet https://curl.haxx.se/ca/cacert.pem
$ export SSL_CERT_FILE=$HOME/cacert.pem

Bron: https://access.redhat.com/articles/ 2039753


Antwoord 12, autoriteit 2%

Ik moet nog een antwoord toevoegen, want net als Craig Glennie ging ik op een wilde gansjacht vanwege de vele berichten die op internet naar dit probleem verwijzen.

Ik gebruik MacPorts, en wat ik oorspronkelijk dacht dat een Python-probleem was, was in feite een MacPorts-probleem: het installeert geen rootcertificaat met de installatie van openssl. De oplossing is om curl-ca-bundle te port install curl-ca-bundle, zoals vermeld in deze blogpost.


Antwoord 13, autoriteit 2%

Oplossing voor Anaconda

Mijn setup is Anaconda Python 3.7 op MacOS met een proxy. De paden zijn anders.

  • Zo krijgt u het juistecertificatenpad:
import ssl
ssl.get_default_verify_paths()

die op mijn systeem produceerde

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

Zodra u weet waar het certificaat naartoe gaat, samenvoegt uhet certificaat dat door de proxy wordt gebruikt aan het einde van dat bestand.

Ik had conda al ingesteld om met mijn proxy te werken, door het volgende uit te voeren:

conda config --set ssl_verify <pathToYourFile>.crt

Als u niet meer weet waar uw certificaat is, kunt u het vinden in ~/.condarc:

ssl_verify: <pathToYourFile>.crt

Nu samenvoegendat bestand aan het einde van /miniconda3/ssl/cert.pem
en verzoeken zouden moeten werken, en in het bijzonder sklearn.datasetsen soortgelijke tools
zou moeten werken.

Verdere waarschuwingen

De andere oplossingen werkten niet omdat de Anaconda-opstelling iets anders is:

  • Het pad Applications/Python\ 3.Xbestaat gewoon niet.

  • Het pad van de onderstaande commando’s is het VERKEERDEpad

from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH

Antwoord 14

Python 2.7.12 (standaard, 29 juli 2016, 15:26:22) heeft het genoemde probleem opgelost. Deze informatie kan iemand anders helpen.


Antwoord 15

Het verbaast me dat al deze instructies mijn probleem niet hebben opgelost. Desalniettemin is de diagnose correct (BTW, ik gebruik Mac en Python3.6.1). Dus, om het juiste deel samen te vatten:

  • Op Mac laat Apple OpenSSL vallen
  • Python gebruikt nu zijn eigen set CA-rootcertificaten
  • Binaire Python-installatie leverde een script om het CA Root-certificaat te installeren dat Python nodig heeft (“/Applications/Python 3.6/Install Certificates.command”)
  • Lees “/Applications/Python 3.6/ReadMe.rtf” voor details

Voor mij werkt het script niet, en al die certifi- en openssl-installaties konden ook niet worden hersteld. Misschien omdat ik meerdere python 2- en 3-installaties heb, evenals veel virtualenv. Uiteindelijk moet ik het met de hand repareren.

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

Als dat je nog steeds niet lukt. Her-/installeer vervolgens OpenSSL ook.

port install openssl

Antwoord 16

Voor Python 3.4+op Centos 6/7, Fedora, installeer gewoon de vertrouwde CA op deze manier:

  1. Kopieer de CA.crt naar /etc/pki/ca-trust/source/anchors/
  2. update-ca-trust force-enable
  3. update-ca-trust extract

Antwoord 17

Ik heb dit gevonden via hier

Ik heb deze oplossing gevonden, plaats deze code aan het begin van je bronbestand:

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

Met deze code wordt de verificatie ongedaan gemaakt, zodat de SSL-certificering niet wordt geverifieerd.


Antwoord 18

Net als jij gebruik ik python 2.7 op mijn oude iMac (OS X 10.6.8), ik heb het probleem ook ondervonden met urllib2.urlopen :

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]

Mijn programma’s werkten prima zonder SSL-certificaatproblemen en plotseling (na het downloaden van programma’s) crashten ze met deze SSL-fout.

Het probleem was de gebruikte versie van python:

  1. Geen probleem met https://www.python.org/downloadsen python- 2.7.9-macosx10.6.pkg

  2. probleem met degene die is geïnstalleerd door Homebrew-tool: “brew install python”, versie in /usr /local/bin.

Een hoofdstuk, genaamd Certificate verification and OpenSSL [CHANGED for Python 2.7.9], in /Applications/Python 2.7/ReadMe.rtflegt het probleem met veel details uit .

Dus, controleer, download en plaats in je PATH de juiste versie van python.


Antwoord 19

Ik schaam me half, want ik had hetzelfde probleem, behalve dat in mijn geval de URL die ik aanraakte geldig was, het certificaat geldig was. Wat niet geldig was, was mijn verbinding met internet. Ik had geen proxy-details toegevoegd aan de browser (IE in dit geval). Hierdoor verliep het verificatieproces niet correct.
Toegevoegd in de proxy-details en mijn python was toen erg blij.


Antwoord 20

De SSL: CERTIFICATE_VERIFY_FAILED-fout kan ook optreden omdat er een tussencertificaat ontbreekt in het ca-certificates-pakket op Linux. In mijn geval ontbrak bijvoorbeeld het tussencertificaat “DigiCert SHA2 Secure Server CA” in het ca-certificates-pakket, ook al bevat de Firefox-browser dit. U kunt achterhalen welk certificaat ontbreekt door de opdracht wgetrechtstreeks uit te voeren op de URL die deze fout veroorzaakt. Vervolgens kunt u op de officiële website naar de bijbehorende link naar het CRT-bestand voor dit certificaat zoeken (bijv. https://www.digicert.com/digicert-root-certificates.htmin mijn geval) van de certificeringsinstantie. Om nu het certificaat op te nemen dat in uw geval ontbreekt, kunt u in plaats daarvan de onderstaande opdrachten uitvoeren met behulp van uw CRT-bestandsdownloadlink:

wget https://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
mv DigiCertSHA2SecureServerCA.crt DigiCertSHA2SecureServerCA.der
openssl x509 -inform DER -outform PEM -in DigiCertSHA2SecureServerCA.der -out DigicertSHA2SecureServerCA.pem.crt
sudo mkdir /usr/share/ca-certificates/extra
sudo cp DigicertSHA2SecureServerCA.pem.crt /usr/share/ca-certificates/extra/
sudo dpkg-reconfigure ca-certificates

Hierna kunt u opnieuw testen met wgetvoor uw URL en met behulp van het python urllib-pakket. Raadpleeg voor meer informatie: https://bugs.launchpad .net/ubuntu/+source/ca-certificates/+bug/1795242


Antwoord 21

Python 2.7 op Amazon EC2 met centOS 7

Ik moest de env-variabele SSL_CERT_DIRinstellen om te verwijzen naar mijn ca-bundledie zich op /etc/ssl/certs/ca-bundle.crt


Antwoord 22

Probeer

pip install –trusted-host pypi.python.org pakketnaam

Het werkte voor mij.


Antwoord 23

Kijk eens naar

/Applications/Python 3.6/Install Certificates.command

U kunt ook naar Applicaties gaan en op Certificates.command klikken


Antwoord 24

In mijn geval kreeg ik deze foutmelding omdat de versies requestsen urllib3incompatibel waren, wat de volgende foutmelding gaf tijdens de installatie:

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

het lukte.


Antwoord 25

Nog een Anaconda-oplossing.Ik kreeg CERTIFICATE_VERIFY_FAILED in mijn Python 2.7-omgeving op macOS. Het blijkt dat de conda-paden slecht waren:

basis (3.7) omgeving:

>>> 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 omgeving (paden bestonden niet!):

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

De oplossing:

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

Antwoord 26

Er zijn gevallen waarin u geen onveilige verbindingen kunt gebruiken of ssl-context niet kunt doorgeven aan urllib-verzoek. Hier mijn oplossing gebaseerd op
https://stackoverflow.com/a/28052583/6709778

In het geval dat u uw eigen certificaatbestand wilt gebruiken

import ssl
def new_ssl_context_decorator(*args, **kwargs):
    kwargs['cafile'] = '/etc/ssl/certs/ca-certificates.crt'
    return ssl.create_default_context(*args, **kwargs)
ssl._create_default_https_context = ssl._create_unverified_context

of u kunt een gedeeld bestand van certifi gebruiken

def new_ssl_context_decorator(*args, **kwargs):
    import certifi
    kwargs['cafile'] = certifi.where()
    return ssl.create_default_context(*args, **kwargs)

Antwoord 27

Als u vCenter 6 gebruikt, moet u in plaats daarvan het vmware-certificaatautoriteitcertificaat van uw vCenter toevoegen aan de lijst met vertrouwde CA’s van uw besturingssysteem. Ga als volgt te werk om uw certificaat te downloaden

  1. Open uw webbrowser.
  2. Navigeer naar https://
  3. Klik in de rechterbenedenhoek op de link Vertrouwde root-CA downloaden

Op Fedora

  1. unzip en verander de extensie van .0 in .cer
  2. Kopieer het naar de /etc/pki/ca-trust/source/anchors/
  3. voer de opdracht update-ca-trust uit.

Links:

  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

Antwoord 28

installatiestappen voor nltk (ik had python3 (3.6.2) al geïnstalleerd in MAC OS X

sudo easy_install pip

gebruik negeer geïnstalleerde optie om het verwijderen van de vorige versie van zes te negeren, anders geeft het een foutmelding tijdens het verwijderen en filmt het niet door

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

Controleer de installatie van pip en python, gebruik de ‘3’ versies

which python python2 python3
which pip pip2 pip3

Controleer of NLTK is geïnstalleerd

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

Installeer een SSL-certificaat voordat u het voorbeeldenboek installeert, anders krijgen we een certificaatfout tijdens het installeren van de voorbeelden

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

Dat heeft de installatie van nltk en nltk_ata voor boekvoorbeelden met succes voltooid


Antwoord 29

Het installeren van PyOpenSSLmet behulp van pipwerkte voor mij (zonder te converteren naar PEM):

pip install PyOpenSSL

Antwoord 30

Ik heb dit probleem opgelost door Fiddler (een HTTP-foutopsporingsproxy) te sluiten, controleer of je een proxy hebt ingeschakeld en probeer het opnieuw.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes