エラーメッセージ
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical
これを出力するのは、厳格なチェックを有効にしたクライアントだけです。つまり、デフォルトで有効な Python 3.13 以降と、openssl verify -x509_strict です。Python は「(_ssl.c:1082)」のようなソースの位置を付け加えます。
Python 3.13+ ssl module — VERIFY_X509_STRICT in create_default_context(), X509_V_ERR_CA_BCONS_NOT_CRITICAL
このエラーの意味
Python 3.13 以降は OpenSSL の厳格な X.509 モードで検証を行い、CA 証明書の basicConstraints 拡張は critical としてマークされていなければならないという RFC 5280 の規則を適用します。チェーン内の CA の basicConstraints は critical フラグなしの CA:TRUE になっているため、CA が信頼されていても OpenSSL はチェーンを拒否します。
発生する理由
CA が「critical」なしのプロファイルから作成された
よくあるbasicConstraints = CA:TRUE と書かれた(critical,CA:TRUE ではない)OpenSSL の設定セクションや、規格に準拠していないテンプレートを持つ CA ツールが、このような CA 証明書を生成します。
クライアントが Python 3.13 以降に移行した
よくある以前の Python のバージョンは VERIFY_X509_STRICT を設定していなかったため、アップグレードするまでは同じ CA で問題なく動作していました。
チェーン内の中間 CA に欠陥がある
ときどきこのチェックは、パス内のすべての CA 証明書に適用されます。準拠しているルートが発行した中間証明書も対象です。
修正方法
- 1.
準拠していない証明書を見つける
チェーン内の各 CA について basicConstraints を出力してください。「critical」がないものは再発行しなければなりません。openssl verify -x509_strict を使うと、厳格モードでの問題がすべて表示されます。
bash openssl x509 -in ca.pem -noout -ext basicConstraints # X509v3 Basic Constraints: <- no "critical" here is the problem # CA:TRUE openssl verify -x509_strict -CAfile ca.pem server.pem - 2.
critical の basicConstraints を付けて CA を再発行する
basicConstraints = critical, CA:TRUE と keyUsage 拡張を付けて、CA 証明書に署名し直してください。同じ鍵とサブジェクトを維持すれば、既存の証明書も新しい CA 証明書で検証できます。
bash openssl req -x509 -new -key ca.key -days 3650 -subj "/CN=Example Private CA" \ -addext "basicConstraints=critical,CA:TRUE" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -out ca.pem - 3.
一時的な回避策:VERIFY_X509_STRICT を解除する
CA を修正するまでの間、1 つのコンテキストに限って 3.13 より前の動作に戻します。チェーン、有効期間、ホスト名の検証は有効なままです。
python # Temporary workaround until the CA is reissued (chain, dates and name are still checked) import ssl ctx = ssl.create_default_context(cafile="ca.pem") ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT