无法在 C++ 中使用 OpenSSL 连接到主机

Can't connect to host using OpenSSL in C++

当我尝试在 C++ 中使用 OpenSSL 通过 HTTPS 连接到某些主机(不是全部)时,出现 OpenSSL 错误 error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure。我正在使用 TLS_client_method SSL 方法。但是,如果我使用 openssl 测试可执行文件,就可以了 - 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 握手中。 Multi-domain 站点通常需要 SNI 并且可能会失败,或者 return 在未提供 SNI 时可能会出现一些不相关的证书。对于像 Cloudflare 这样的 CDN 也是如此,其中不同的域可以通过相同的 IP 地址访问,但应该产生不同的证书。

... I tried to connect to hostiman.ru

例如 hostiman.ru 就是这种情况。使用 SNI(默认情况下由较新的 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)