トラブル内容
Pythonにおいて、RESTful APIサービスを利用してデータを取得しようとした際に、SSLError:CERTIFICATE_VERIFY_FAILED が発生した。
開発環境
OS:Windows 10
IDE:PyCharm
import requests
# URLを指定する
url = "https://xxx.com/test"
# データを取得する
response = requests.get(url)
>> requests.exceptions.SSLError:
>> HTTPSConnectionPool(host='xxx.com', port=443): Max retries exceeded with url: /test
>> (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)')))
原因
Pythonのrequestsモジュールは、HTTPS通信において、ルート証明書情報を参照する際に、Windowsの証明書マネージャ(certmgr.msc)を参照せず、certifiモジュールの cacert.pem ファイルを参照している。
cacert.pem ファイルはルート証明書情報が記載されているが、今回のRESTful APIサービスに関するルート証明書情報は記載されていないため、SSL接続ができなかった。
インターネット上に公開されている情報を取得する際に、cacert.pem ファイルにルート証明書情報が記載されていない場合はSSL接続ができない可能性がある。
対策内容
ルート証明書情報を取得し、certifiモジュールに転記する
(1)windowsキー を挿下 → certmgr.msc と入力 → certmgr.msc を選択する
(2)信頼されたルート証明機関 → 証明書 → 該当のルート証明書を右クリック → すべてタスク → エクスポート を選択する
(3)次へ → 使用する形式:Base 64 encoded X.509 (.CER) → 次へ → エクスポートするフォルダとファイル名を選択 → 完了 → OK でルート証明書情報をエクスポートする
(4)certifiモジュールの cacert.pem ファイルが保存されているフォルダを開く
(例)
C:\ProgramData\Miniconda3\envs\test\Lib\site-packages\certifi
(5)cacert.pem → cacert.txt 等に拡張子を変更し、内容を変更できるようにする
(6)export_cer_file.cer(エクスポートしたルート証明書情報) → export_cer_file.txt 等に拡張子を変更し、内容を変更できるようにする
(7)export_cer_file.txt に記載されている内容を、cacert.txt の末尾にコピー&ペーストする
(8)cacert.pem → cacert.txt に拡張子を戻す
上記の手順でcacert.pem にルート証明書情報に転記することで、SSL接続に成功する