WindowsのPythonでSSL証明書検証に失敗したときは「truststore」を試そう

WindowsのPythonでSSL証明書検証に失敗したときは「truststore」を試そう

WindowsのPythonでHTTPS通信を行ったとき、ブラウザでは正常に開けるサイトなのに、Pythonでは証明書エラーになることがあります。そんなときに試したいのが truststore です。

どんなエラー?

例えば requests や urllib3 で通信したときに、次のような例外が出るケースです。

ssl.SSLCertVerificationError:
[SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed:
unable to get local issuer certificate

原因は、信頼できる認証局(CA)までの証明書チェーンを検証できないこと。certifi のCA証明書セットとWindowsの証明書ストアの違い、中間証明書の不足、プロキシ・セキュリティソフトによるHTTPS検査などが関係する場合があります。

truststoreとは?

truststore は、PythonからOS標準の証明書検証機構を使えるようにするライブラリです。WindowsではCryptoAPIを利用します。Windows側で管理されている認証局を利用でき、中間証明書の取得などもOSの仕組みを活用できます。

ここで注意したいのは、標準のPythonがWindowsの証明書ストアを全く使わないわけではないということ。Pythonの標準sslもWindowsのCA/ROOTストアを読み込めます。ただし、証明書チェーンの検証処理などがWindowsネイティブの仕組みと異なるため、truststoreで改善するケースがあります。

導入手順はたった2ステップ

1. インストール

Python 3.10以降で利用できます。PowerShellまたはコマンドプロンプトで実行します。

py -m pip install truststore

2. プログラムの先頭で有効化

import truststore

# HTTPS関連ライブラリを読み込む前に実行
truststore.inject_into_ssl()

import requests

response = requests.get("https://www.python.org/", timeout=10)
response.raise_for_status()
print(response.status_code)

これだけです。inject_into_ssl() は、なるべくアプリケーション起動直後、requests などをインポートする前に呼び出します。すでに読み込まれたライブラリには反映されない場合があります。

なお、inject_into_ssl() はアプリケーションや単独スクリプト向けです。配布するライブラリ内部では勝手にグローバル設定を変更せず、必要に応じて truststore.SSLContext を明示的に渡す設計が推奨されています。

それでも直らない場合

  • Windowsの日付と時刻が正しいか確認する。
  • サーバー側の証明書の期限・ホスト名・中間証明書チェーンに問題がないか確認する。
  • プロキシやウイルス対策ソフトがHTTPS通信を検査している場合、使用するCA証明書が適切に信頼されているか確認する。
  • 仮想環境やEXE化環境では、実際に動いているPython・依存ライブラリ・インポート順序を確認する。

やってはいけない対処:requests.get(..., verify=False) や ssl._create_unverified_context() で証明書検証を無効化すること。エラーは消えても、中間者攻撃を検出できなくなる危険があります。

pipの証明書エラーとは別の話

pip 24.2以降は、Python 3.10以上でシステム証明書とcertifiを併用して検証する仕組みが標準で利用されています。一方、pipがそうなっていても、自作PythonアプリのHTTPS通信が自動的に全部truststoreになるわけではありません。

Windowsでブラウザだけ正常、Pythonだけ証明書検証に失敗する場合は、原因を確認したうえで truststore を試す価値があります。

参考資料

コメントを残す