本文へスキップ
ecdsa.com
Python 3.13+ ssl modulePython の cryptography

エラーメッセージ

[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 はチェーンを拒否します。

発生する理由

修正方法

  1. 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. 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. 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

関連するエラー

署名エラーデータベースをすべて見る