错误信息
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 名称”列表中的 CA 签发的证书;如果没有匹配的证书,就什么都不发送。
代理在 mTLS 服务器之前终止了 TLS
偶见位于客户端和服务器之间的负载均衡器或代理终止了第一段 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