当我尝试使用 C++ 中的 OpenSSL 通过 HTTPS 连接到某些主机(并非全部)时,出现 OpenSSL 错误 error:14094410:SSL 例程:ssl3_read_bytes:sslv3 警报握手失败。我正在使用 TLS_client_...
当我尝试使用 C++ 中的 OpenSSL 通过 HTTPS 连接到某些主机(并非全部)时,出现 OpenSSL 错误 error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
。我正在使用 TLS_client_method
SSL 方法。但如果我使用 openssl test 可执行文件,则没问题 - 我的 openssl s_client -connect host:443 -tls1_2
连接代码如下:
const SSL_METHOD* method = TLS_client_method();
inet->ssl_ctx = SSL_CTX_new(method);
inet->ssl = SSL_new(inet->ssl_ctx);
SSL_set_fd(inet->ssl, s);
int err = SSL_connect(inet->ssl);
为什么?也许我需要一些 .pem/ .pm 文件?我不知道,但我在某个地方见过。
您的代码在连接到服务器时不使用 SNI 扩展,即未将服务器的主机名包含在 TLS 握手中。多域站点通常需要 SNI,当未提供 SNI 时可能会失败或返回一些不相关的证书。对于像 Cloudflare 这样的 CDN 也是如此,其中不同的域可以通过相同的 IP 地址访问,但应该导致不同的证书。
...我尝试连接到 hostiman.ru
版本默认 s_client
设置
$ openssl s_client -connect hostiman.ru:443 -tls1_2
CONNECTED(00000005)
...
depth=0 C = US, ST = CA, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com
...
Cipher : ECDHE-ECDSA-CHACHA20-POLY1305
如果没有 SNI,它看起来会像这样:
$ openssl s_client -connect hostiman.ru:443 -tls1_2 -noservername
CONNECTED(00000005)
140420123775424:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1528:SSL alert number 40
...
Cipher : 0000
要在客户端中设置 SNI,请使用 SSL_set_tlsext_host_name ,即
inet->ssl = SSL_new(inet->ssl_ctx);
SSL_set_tlsext_host_name(inet->ssl, servername)