Сообщение об ошибке
SSL routines:ssl3_read_bytes:tlsv13 alert certificate required
Также выводится как
- error:0A00045C:SSL routines::tlsv13 alert certificate required
- SSL alert number 116
OpenSSL выводит «error:0A00045C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required:…:SSL alert number 116»; curl выводит «curl: (56) OpenSSL SSL_read: OpenSSL/<version>: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0». В TLS 1.2 та же ситуация обычно заканчивается не этим оповещением, а handshake_failure (оповещение 40).
OpenSSL (client side) — TLS 1.3 alert 116 (certificate_required) from a mutual-TLS server
Что это означает
Сервер требует взаимную TLS-аутентификацию, а клиент завершил рукопожатие TLS 1.3, не предъявив сертификат, поэтому сервер ответил оповещением 116 (certificate_required). В TLS 1.3 клиентский сертификат проверяется уже после того, как клиент считает рукопожатие завершённым, поэтому инструменты вроде curl сообщают об ошибке при первом чтении (код завершения curl 56), а не при установке соединения.
Почему это происходит
Клиентский сертификат не настроен
частоКлиенту не передали сертификат и ключ (curl без --cert, библиотека без параметра клиентского сертификата, новая машина, на которой сертификат не установлен).
Сертификат у клиента был, но не от принимаемого CA
иногдаКлиенты, которые выбирают сертификат автоматически (браузеры, некоторые библиотеки), отправляют только сертификат, выпущенный CA из списка «acceptable CA names» сервера; если ни один не подходит, они не отправляют ничего.
Прокси терминирует TLS перед сервером с mTLS
иногдаБалансировщик нагрузки или прокси между клиентом и сервером терминирует первое TLS-соединение и открывает до бэкенда, который требует клиентский сертификат, собственное соединение без такого сертификата.
Как исправить
- 1.
Предъявите клиентский сертификат
Передайте клиенту сертификат и закрытый ключ (curl --cert/--key, s_client -cert/-key, параметр клиентского сертификата в HTTP-библиотеке).
bash openssl s_client -connect mtls.example.com:443 -servername mtls.example.com \ -cert client.pem -key client.key -brief </dev/null curl --cert client.pem --key client.key https://mtls.example.com/ - 2.
Посмотрите, какие CA принимает сервер
openssl s_client выводит список «Acceptable client certificate CA names», который отправляет сервер; цепочка от вашего сертификата должна вести к одному из них.
bash # Which CAs does the server accept client certificates from? openssl s_client -connect mtls.example.com:443 -servername mtls.example.com </dev/null 2>/dev/null \ | sed -n '/Acceptable client certificate CA names/,/^Requested/p' - 3.
Проверьте сам сертификат
Он должен быть в пределах срока действия и выпущен принимаемым CA, а его расширение extendedKeyUsage (если оно есть) должно содержать clientAuth.
bash # The client certificate must be valid, issued by an accepted CA, and allow clientAuth openssl x509 -in client.pem -noout -subject -issuer -dates -ext extendedKeyUsage
Связанные ошибки
SSL routines:tls_process_client_certificate:peer did not return a certificateOpenSSL (server side, mutual TLS)SSL routines:ssl3_read_bytes:ssl/tls alert handshake failureOpenSSL (client side)SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknow…nginx error log / OpenSSL400 No required SSL certificate was sentnginx