web-dev-qa-db-ja.com

urllibと "SSL:CERTIFICATE_VERIFY_FAILED"エラー

次のようなエラーが表示されます。

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を使うことを要求しています。検証を回避するにはどうすればよいですか。

214
user3724476

just を検証を回避したい場合は、新しい 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()  # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)

これで問題は解決するはずですが、実際には問題を解決しているわけではありませんが、[SSL: CERTIFICATE_VERIFY_FAILED]は表示されません。証明書を検証していないからです。

上記に加えて、あなたがこれらの問題を見ている理由についてもっと知りたいならば、 PEP 476 を見たいと思うでしょう。

このPEPは、X509証明書の署名の検証と、デフォルトではPythonのHTTPクライアントのホスト名の検証を有効にすることを提案しています。コールごとのオプトアウトの対象となります。この変更は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

これは、未検証のコンテキストを作成する機能で、コンテキスト作成のデフォルト機能をオーバーライドします。

PEPに記載されているようにこれに注意してください。

このガイダンスは、HTTPS接続での証明書検証をまだサポートしていないレガシー環境でこのPEPを実装する新しいバージョンのPythonを採用したいシステム管理者を主な目的としています。たとえば、管理者は、Python用の標準的なオペレーティング環境のsitecustomize.pyに上記のmonkeypatchを追加することでオプトアウトできます。 アプリケーションやライブラリは、この変更プロセスをワイドにするべきではありません (システム管理者が制御する設定への応答を除いて)。

ソフトウェアで証明書を検証しないのがなぜ悪いのかについての論文を読みたいのなら - ここでそれを見つけることができます

234
Noelkd

これはあなたの特定の問題を解決するものではありませんが、このスレッドが「SSL:CERTIFICATE_VERIFY_FAILED」に対するGoogleのトップの結果であるため、ここに掲載しています。

OSXにPython 3.6をインストールし、https://サイトに接続しようとしたときに "SSL:CERTIFICATE_VERIFY_FAILED"エラーが発生する場合は、おそらくOSX上のPython 3.6に証明書がまったくなく、SSLを検証できないためです。接続これはOSX上の3.6のための変更であり、証明書のcertifiパッケージをインストールするインストール後の手順が必要です。これはReadMeに文書化されていて、/Applications/Python\ 3.6/ReadMe.rtfにあります。

ReadMeはあなたにcertifiをインストールするだけのポストインストールスクリプトをあなたに実行させるでしょう:/Applications/Python\ 3.6/Install\ Certificates.command

リリースノートには、もう少し情報があります: https://www.python.org/downloads/release/python-360/

277
Craig Glennie

Craig Glennieの答えを詳しく説明すると、

macOs Sierra上のPython 3.6.1でのインストール

Bash端末にこれを入力すると問題が解決しました。

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

私のMac OS X用ソリューション:

1)公式のPython言語ウェブサイト https://www.python.org/downloads/ からダウンロードしたネイティブアプリのPythonインストーラを使用してPython 3.6.5にアップグレードします。

私は、このインストーラが新しいPython用のリンクとシンボリックリンクを自作よりはるかに良く更新していることに気付きました。

2)更新されたPython 3.6ディレクトリにある "./Install Certificates.command"を使用して新しい証明書をインストールします。

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

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ファイルを編集して、ファイルの末尾にドメイン検証証明書を貼り付けます。
  5. ファイルを保存してリクエストを楽しんでください。
26
Bruno Gabuzomeu

あなたの環境変数にこれを追加してみることができます:

PYTHONHTTPSVERIFY=0 

これは all HTTP検証を無効にするのでちょっとしたハンマーアプローチですが、検証が必要でない場合は効果的な解決策になるかもしれません。

26
Chris Halcrow

Python 3.4、3.5、および3.6 urllib.request.urlopenを使用していましたが、同様の問題がありました。 (これは、Python 2の urllib2ドキュメンテーションページ の先頭にあるメモによると、Python 3に相当するurllib2の一部です。)

私の解決策はpip install certificertifi をインストールすることでした。

... TLSホストの身元を確認しながらSSL証明書の信頼性を検証するためのルート証明書の厳選コレクション。

それから、私が以前にちょうど持っていた私のコードで:

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のドキュメント を正しく読んだ場合、それにはcafile引数もあります。そのため、urllib2.urlopen([...], certifi.where())はPython 2.7でも動作するかもしれません。

14
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

ここから撮影した https://Gist.github.com/michaelrice/a6794a017e349fc65d01

12
Prostak

私がコメントで書いたように、この問題はおそらく this SO answer に関連しています。

つまり、証明書を検証する方法は複数あります。 OpenSSLで使用される検証は、システムにある信頼されたルート証明書と互換性がありません。 OpenSSLはPythonで使用されています。

Verisign Class 3公開一次認証局 の不足している証明書を取得してから、 Pythonのドキュメント に従ってcafileオプションを使用することができます。

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

Python 3.4+ on Centos 6/7、Fedora の場合は、このように信頼できるCAをインストールしてください。

  1. CA.crtを/etc/pki/ca-trust/source/anchors/にコピーします
  2. update-ca-trust force-enable
  3. update-ca-trust extract
4
Cherif KAOUA

私は私の場合は、当たっていたURLが有効だったこと、証明書が有効だったことを除いて、私は同じ問題を抱えていたので、私は頭を恥ずかしそうにぶら下げます。無効だったのは私のWebへの接続でした。ブラウザ(この場合はIE)にプロキシの詳細を追加できませんでした。これにより、検証プロセスが正しく行われなくなりました。
プロキシの詳細に追加され、私のpythonはとても幸せでした。

3
Ads

私は別の答えを追加する必要があるのは、Craig Glennieと同じように、多くの投稿がWeb上でこの問題に言及しているために野生のガチョウの追跡を行ったためです。

私はMacPortsを使用していますが、私がもともとPythonの問題であると思ったのは実際にはMacPortsの問題でした。opensslのインストールではルート証明書をインストールしません。 このブログ記事 に記載されているように、解決策はport install curl-ca-bundleです。

3
corwin.amber

Python 2.7.12(デフォルト、2016年7月29日15時26分22秒)で上記の問題が修正されました。この情報は他の人に役立つかもしれません。

3
caot

私はこれらすべての指示が私の問題を解決しなかったことに驚いています。それにもかかわらず、診断は正しいです(ところで、私はMacとPython3.6.1を使っています)。だから、正しい部分をまとめると:

  • Macでは、AppleはOpenSSLを落としています
  • Pythonは独自のCAルート証明書を使用するようになりました
  • バイナリPythonインストールは、Pythonが必要とするCAルート証明書をインストールするためのスクリプトを提供しました( "/ Applications/Python 3.6/Install Certificates.command")。
  • 詳細は "/ Applications/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
2
berniey

あなたのように、私は私の古いiMac(OS X 10.6.8)上でpython 2.7を使っています。

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]

私のプログラムはSSL証明書の問題がなく正常に動作していました、そして突然(プログラムをダウンロードした後に)、彼らはこの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という章で、問題を多くの詳細と共に説明しています。

それで、あなたのPATHに正しいバージョンのpythonをチェックし、ダウンロードして入れてください。

2

やってみる

pip install --trusted-Host pypi.python.orgパッケージ名

それは私のために働きました。

1
user3603105

を見てみましょう

/アプリケーション/ Python 3.6/Certificates.commandのインストール

また、アプリケーションにアクセスしてCertificates.commandをクリックすることもできます

1
Danielle Cohen

CentOS 7を搭載したAmazon EC2上のPython 2.7

Env変数SSL_CERT_DIRを、ca-bundleにある自分の/etc/ssl/certs/ca-bundle.crtを指すように設定しなければなりませんでした。

1
Brian McCall

この問題に遭遇したmechanizeを使っている人のために、以下は、あなたが機械化されたBrowserインスタンスに同じテクニックをどのように適用できるかです:

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

VCenter 6を使用している場合は、代わりにOSの信頼性のあるCAのリストにvCenterのVMware認証局証明書を追加する必要があります。証明書をダウンロードするには、次の手順に従います。

  1. Webブラウザを開きます。
  2. Https://に移動します
  3. 右下隅にあるDownload Trusted Root CAリンクをクリックしてください。

Fedoraについて

  1. 解凍し、拡張子を.0から.cerに変更します。
  2. / etc/pki/ca-trust/source/anchors /にコピーしてください。
  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
0
nobler1050

ここではすでにたくさんの答えがありますが、私たちは非常に特殊なケースでこれに遭遇し、調査に多くの時間を費やしたので、さらに別のものを追加しました。次のような場合に見ました。

  • Debian-stretch-slim dockerコンテナに
  • デフォルトのPython 3.5.3 easy_install3
  • Kubernetesクラスタのcert-managerを使って登録されたLetsEncrypt証明書

pip3およびopensslコマンドラインは両方とも証明書を検証でき、easy_install3は他のLetsEncrypt証明書を正常に検証できました。

回避策は、最新のPython(当時は3.7.3)をソースから構築することでした。 ここ の指示は詳細で、従うのが簡単です。

0
aschmied

私の場合、requestsurllib3のバージョンに互換性がないため、このエラーが発生していました。インストール中に次のエラーが発生しました。

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

トリックしました。

0
fabio.sang

Python 2.7では、ファイルC:\ Python27\lib\site-packages\certifi\cacert.pemの最後に信頼されたルートCAの詳細を追加することが助けになりました

その後、私は(管理者権限を使用して)実行しましたpip install --trusted-Host pypi.python.org --trusted-Host pypi.org --trusted-Host files.pythonhosted.org packageName

0
MD5

Linux Python3.6の場合、これは私にとってうまくいきました。

コマンドラインからpyopensslとcertifiをインストールする

Sudo pip3 install -U pyopenssl
Sudo pip3 install certifi

そして私のpython3スクリプトで、verify = '/ usr/lib/python3.6/site-packages/certifi/cacert.pem'を以下のように追加しました:

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

私はこれを見つけました ここ

私はこの解決策を見つけました、あなたのソースファイルの始めにこのコードを挿入してください:

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

このコードは検証を元に戻すため、SSL証明書は検証されません。

nltkのインストール手順(私はpython3(3.6.2)をすでにMAC OS Xにインストールしていました)

Sudo easy_install pip

以前のバージョンの6をアンインストールすることを無視するには、ignore installedオプションを使用します。

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のインストールは正常に完了しました。

0
Narasimha Sai

アナコンダ向けソリューション

私の設定はプロキシを備えたMacOS上のAnaconda Python 3.7です。パスは異なります。

  • これは、 correct certificatesパスを取得する方法です。
import ssl
ssl.get_default_verify_paths()

私のシステムではどの

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

証明書がどこにあるのかがわかったら、プロキシによってそのファイルの最後まで使用された証明書を連結します。

次のコマンドを実行して、プロキシと連携するようにcondaを既に設定しています。

conda config --set ssl_verify <pathToYourFile>.crt

自分の証明書がどこにあるか覚えていない場合は、~/.condarcにあります。

ssl_verify: <pathToYourFile>.crt

そのファイルを連結 _ /miniconda3/ssl/cert.pemの最後に追加すると、リクエストは動作するはずです。特にsklearn.datasetsと同様のツールは動作するはずです。

さらなる警告

Anacondaの設定が少し異なるため、他の解決策は機能しませんでした。

  • パスApplications/Python\ 3.Xは単に存在しません。

  • 以下のコマンドによって提供されるパスは _ wrong _ pathです。

from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
0
Leo

PyOpenSSLを使用してpipをインストールすることは私にとってはうまくいきました(PEMに変換せずに):

pip install PyOpenSSL
0
averma93

Fiddler(HTTPデバッグプロキシ)を閉じてプロキシが有効になっているかどうかを確認してもう一度試して、この問題を解決しました。

0
vperezb

Macにcertifiをインストールすることが私の問題を解決しました:

pip install certifi
0
Snehal Parmar

もう1つのアナコンダのソリューション。 macOS上のPython 2.7環境でCERTIFICATE_VERIFY_FAILEDを取得していました。 condaのパスが悪かったことがわかりました。

ベース(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環境(パスが存在しませんでした!):

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

修正:

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