Сообщение об ошибке
[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+ проверяет сертификаты в строгом режиме X.509 OpenSSL, который применяет правило RFC 5280: расширение basicConstraints в сертификате CA должно быть помечено как критическое (critical). У CA в вашей цепочке указано basicConstraints CA:TRUE без флага critical, поэтому OpenSSL отклоняет цепочку, хотя этот CA и входит в число доверенных.
Почему это происходит
CA создан по профилю без «critical»
частоТакие сертификаты CA получаются из раздела конфигурации OpenSSL с basicConstraints = CA:TRUE (вместо critical,CA:TRUE) или из инструмента для CA с шаблоном, который не соответствует стандарту.
Клиент перешёл на Python 3.13 или новее
частоБолее ранние версии Python не устанавливали VERIFY_X509_STRICT, поэтому тот же CA работал до обновления.
Дефект есть у промежуточного CA в цепочке
иногдаПроверка применяется к каждому сертификату CA в пути, включая промежуточные сертификаты, выпущенные корневым CA, который соответствует стандарту.
Как исправить
- 1.
Найдите сертификат, не соответствующий стандарту
Выведите basicConstraints для каждого CA в цепочке; сертификат CA без «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.
Перевыпустите CA с критическим расширением basicConstraints
Подпишите сертификат CA заново с basicConstraints = critical, CA:TRUE и расширением keyUsage. Если сохранить тот же ключ и субъект, уже выпущенные сертификаты будут проходить проверку по новому сертификату 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
Сброс флага возвращает для одного контекста поведение версий до 3.13 на то время, пока CA исправляют. Проверка цепочки, сроков действия и имени хоста остаётся включённой.
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