urllib et erreur" SSL: la vérification du certificat a échoué"
Je reçois l'erreur suivante:
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)>
C'est le code qui cause cette erreur:
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)
L'API que j'utilise nécessite que J'utilise HTTPS. Comment puis-je le faire contourner la vérification?
24 réponses
{Si vous[6]}juste voulez contourner la vérification, vous pouvez créer un nouveau SSLContext. Par défaut, les contextes nouvellement créés utilisent CERT_NONE .
Être prudent avec ce comme indiqué dans la section 17.3.7.2.1
Lors de l'appel direct du constructeur SSLContext, CERT_NONE est la valeur par défaut. Comme il n'authentifie pas l'autre homologue, il peut être non sécurisé, en particulier en mode client où la plupart du temps vous souhaitez assurer l'authenticité du serveur à qui vous parlez. Par conséquent, en mode client, il est fortement recommandé D'utiliser CERT_REQUIRED.
, Mais si vous voulez juste qu'il fonctionne maintenant pour une autre raison, vous pouvez effectuer les opérations suivantes, vous devrez import ssl
ainsi:
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)
Cela devrait contourner votre problème mais vous ne résolvez pas vraiment l'un des problèmes,mais vous ne verrez pas le [SSL: CERTIFICATE_VERIFY_FAILED]
parce que vous ne Vérifiez pas le certificat!
Pour ajouter à ce qui précède, si vous voulez en savoir plus sur pourquoi vous voyez ces questions que vous voudrez jeter un oeil à PEP 476 .
Ce PEP propose d'activer la vérification des signatures de certificat X509, ainsi que la vérification du nom d'hôte pour les clients HTTP de Python par défaut, sous réserve d'une désactivation par appel. Cette modification serait appliquée à Python 2.7, Python 3.4 et Python 3.5.
Il y a un opt out conseillé qui n'est pas différent de mon conseil ci-dessus:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
, Il dispose également d'un hautement déconseillé option via monkeypatching {[9] } que vous ne voyez pas souvent en python:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
Qui remplace la fonction par défaut pour la création de contexte par la fonction pour créer un contexte non vérifié.
Si vous voulez lire un article sur pourquoi ne pas valider les certificats de mauvais logiciels , vous pouvez le trouver ici!
Ce n'est pas une solution à votre problème spécifique, mais je le mets ici parce que ce fil est le meilleur résultat Google pour "SSL: CERTIFICATE_VERIFY_FAILED", et cela m'a conduit sur une chasse à l'oie sauvage.
Si vous avez installé Python 3.6 sur OSX et que vous obtenez L'erreur" SSL: CERTIFICATE_VERIFY_FAILED " lorsque vous essayez de vous connecter à un site https://, c'est probablement parce que Python 3.6 sur OSX n'a aucun certificat et ne peut valider aucune connexion SSL. Ceci est un changement pour 3.6 sur OSX, et nécessite une étape post-installation, qui installe le paquet de certificats certifi
. Ceci est documenté dans le ReadMe, que vous devriez trouver à /Applications/Python\ 3.6/ReadMe.rtf
Le ReadMe vous fera exécuter ce script post-installation, qui s'installe simplementcertifi
: /Applications/Python\ 3.6/Install\ Certificates.command
Les notes de version ont plus d'Informations: https://www.python.org/downloads/release/python-360/
Pour développer la réponse de Craig Glennie (désolé pas assez de réputation pour commenter):
En python 3.6.1 sur MacOs Sierra
Entrer ceci dans le terminal bash a résolu le problème:
pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command
Sous Windows, Python ne regarde pas le certificat système, il utilise le sien situé à ?\lib\site-packages\certifi\cacert.pem
.
La solution à votre problème:
- téléchargez le certificat de validation de domaine en tant que *.fichier crt ou * PEM
- , ouvrez le fichier dans l'éditeur et copiez son contenu dans le presse-papiers
- trouver votre
cacert.pem
emplacement:from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
- modifiez le fichier
cacert.pem
et collez votre certificat de validation de domaine à la fin du fichier. - enregistrez le fichier et profitez des demandes!
Vous pouvez essayer d'ajouter ceci à vos variables d'environnement:
PYTHONHTTPSVERIFY=0
Notez que cela désactivera All la vérification HTTP est donc un peu une approche sledgehammer, mais si la vérification n'est pas requise, elle peut être une solution efficace.
Ma solution pour Mac OS X:
1) Mise à niveau vers Python 3.6.5 en utilisant l'application native Python installer téléchargé à partir du site officiel de la langue Python https://www.python.org/downloads/
J'ai trouvé que ce programme d'installation prend soin de mettre à jour les liens et les liens symboliques pour le nouveau Python beaucoup mieux que homebrew.
2) Installer un nouveau certificat en utilisant "./ Installer Les Certificats.commande " qui se trouve dans le répertoire Python 3.6 actualisé
> 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
Pris d'ici https://gist.github.com/michaelrice/a6794a017e349fc65d01
Comme je l'ai écrit dans un commentaire, ce problème est probablement lié à cette réponse SO .
En bref: il existe plusieurs façons de vérifier le certificat. La vérification utilisée par OpenSSL est incompatible avec les certificats racine de confiance que vous avez sur votre système. OpenSSL est utilisé par Python.
Vous pouvez essayer d'obtenir le certificat manquant pour Verisign Class 3 Public Primary Certification Authority et ensuite utiliser l'option cafile
selon Python documentation :
urllib2.urlopen(req, cafile="verisign.pem")
J'avais un problème similaire, bien que j'utilisais urllib.request.urlopen
dans Python 3.4, 3.5 et 3.6. (C'est une partie de l'Python 3 équivalent de urllib2
, par la remarque à la tête de Python 2urllib2
page de documentation.)
Ma solution a été de pip install certifi
pour installer certifi
, qui a:
... une collection soigneusement organisée de certificats racine pour valider la fiabilité des certificats SSL tout en vérifiant l'identité de TLS hôte.
Ensuite, dans mon code où je viens d'avoir:
import urllib.request as urlrq
resp = urlrq.urlopen('https://foo.com/bar/baz.html')
Je l'ai révisé à:
import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://foo.com/bar/baz.html', cafile=certifi.where())
Si je lis le urllib2.urlopen
documentation correctement, il a aussi un argument cafile
. Donc, urllib2.urlopen([...], certifi.where())
pourrait aussi fonctionner pour Python 2.7.
Pour Python 3.4+ sur Centos 6/7,Fedora, il suffit d'installer l'autorité de certification de confiance de cette façon :
- Copiez L'autorité de certification.crt à
/etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
update-ca-trust extract
Je me pends la tête en demi-honte, car j'ai eu le même problème, sauf que dans mon cas, l'URL que je frappais était valide, le certificat était valide. Ce qui n'était pas valide a été ma connexion internet. J'avais échoué à ajouter des détails de proxy dans le navigateur (C'est-à-dire dans ce cas). Cela a empêché le processus de vérification de se produire correctement.
Ajouté dans les détails du proxy et mon python était alors très heureux .
Comme vous, j'utilise python 2.7 sur mon ancien iMac (OS X 10.6.8), j'ai rencontré le problème aussi, en utilisant urllib2.urlopen:
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
Mes Programmes fonctionnaient bien sans problèmes de certificat SSL et soudainement (après avoir téléchargé des programmes), ils se sont écrasés avec cette erreur SSL.
Le problème était la version de python utilisée :
Pas de problème avec https://www.python.org/downloads {[13] } et python-2.7.9-macosx10. 6.pkg
Problème avec celui installé par Homebrew outil : "brew installer python", version située dans / usr / local / bin.
Un chapitre, intitulé Certificate verification and OpenSSL [CHANGED for Python 2.7.9]
, de /Applications/Python 2.7/ReadMe.rtf
explique le problème avec de nombreux détails.
Alors, vérifiez, téléchargez et mettez dans votre chemin la bonne version de python.
Essayez
Pip install --de confiance-accueil pypi.python.org packagename
Ça a marché pour moi.
Je suis surpris que toutes ces instructions n'aient pas résolu mon problème. Néanmoins, le diagnostic est correct (BTW, j'utilise Mac et Python3.6.1). Donc, pour résumer la partie correcte :
- sur Mac, Apple abandonne OpenSSL
- Python utilise maintenant son propre ensemble de certificat racine CA
- L'installation Python binaire a fourni un script pour installer le certificat racine de L'autorité de certification dont Python a besoin ("/Applications/Python 3.6 / install Certificates.commande")
- Lire " / Applications / Python 3.6 / ReadMe.rtf" pour plus de détails
Pour moi, le script ne fonctionne pas, et toutes ces installations certifi et openssl n'ont pas réussi à réparer aussi. Peut-être parce que j'ai plusieurs installations python 2 et 3, ainsi que de nombreux virtualenv. À la fin, je dois le réparer à la main.
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
Si cela vous échoue toujours. Puis re / installer OpenSSL ainsi.
port install openssl
Je dois ajouter une autre réponse parce que tout comme Craig Glennie, je suis allé sur une chasse à l'oie sauvage en raison des nombreux messages se référant à ce problème à travers le Web.
J'utilise MacPorts, et ce que je pensais à L'origine être un problème Python était en fait un problème MacPorts: il n'installe pas de certificat racine avec son installation d'openssl. La solution est de port install curl-ca-bundle
, comme mentionné dans Cet article de blog .
Jetez un oeil à
/Applications/Python 3.6 / Certificats D'Installation.commande
Vous pouvez aussi aller à Aplications et cliquer sur Certificats.commande
Si vous êtes sur vCenter 6, Vous devez plutôt ajouter le certificat d'autorité de certification vmware de votre vCenter à la liste des CA de confiance de votre système d'exploitation. pour télécharger votre certificat, procédez comme suit
- Ouvrez votre navigateur Web.
- Accédez à https://
- dans le coin inférieur droit, cliquez sur le lien Download Trusted Root CA
Sur Fedora
- décompressez et modifiez l'extension de .0 à .cer
- Copier dans /etc/pki/ca-confiance/source/ancrages/
- Exécutez le mise à jour-autorité de certification de confiance de commande.
Liens:
Python 2.7.12 (par défaut, Jul 29 2016, 15: 26: 22) correction du problème mentionné. Cette information peut aider quelqu'un d'autre.
Étapes D'installation pour nltk (j'avais python3 (3.6.2) déjà installé dans MAC OS X
sudo easy_install pip
Utilisez l'option Ignorer installé pour ignorer la désinstallation de la version précédente de six, sinon, il donne une erreur lors de la désinstallation et ne filme pas
sudo pip3 install -U nltk --ignore-installed six
Vérifiez l'installation de pip et python, utilisez les versions ' 3 '
which python python2 python3
which pip pip2 pip3
Vérifiez si NLTK est installé
python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']
Installez le certificat SSL avant d'installer le livre d'exemples, sinon nous allons erreur de certificat tout installation des exemples
/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book
Qui a terminé l'installation avec succès de nltk et nltk_ata pour les exemples de livres
L'installation de PyOpenSSL
en utilisant pip
a fonctionné pour moi (sans conversion en PEM):
pip install PyOpenSSL
J'ai eu ce problème résolu en fermant Fiddler (un proxy de débogage HTTP) vérifiez si vous avez un proxy activé et réessayez.
Python 2.7 sur Amazon EC2 avec centOS 7
J'ai dû mettre la variable env SSL_CERT_DIR
pour pointer vers mon ca-bundle
, qui était située à /etc/ssl/certs/ca-bundle.crt
Dans Python 2.7 ajout de détails D'autorité de certification racine de confiance à la fin du fichier C:\Python27\lib\site-packages\certifi\cacert.PEM a aidé
Après cela, j'ai couru (en utilisant les droits d'administrateur) pip install --de confiance-accueil pypi.python.org --de confiance-accueil pypi.org --de confiance-accueil files.pythonhosted.org packageName
ln -s /usr/local/share/certs/ca-root-nss.crt /etc/ssl/cert.pem
(FreeBSD 10.1
)