gpt4 book ai didi

c++ - 在与 Asio 和 OpenSSL 握手期间,*某些*网站上出现错误的版本号错误

转载 作者:行者123 更新时间:2023-12-04 22:36:56 24 4
gpt4 key购买 nike

我正在尝试使用 Asio 和 OpenSSL 发送 https 网络请求。我的代码在我尝试过的大多数网站上运行良好,但在其他一些网站上,握手期间出现错误 handshake: wrong version number (SSL routines, ssl3_get_record) .
我发现有些人遇到这个问题是因为他们在代理后面,或者因为他们试图连接到端口 80 而不是端口 443,但这里不是这种情况(据我所知),因为完全相同的代码(见下文举个例子)适用于我尝试过的大多数网站。
我试图用wireshark检查,看看我是否能发现有错误的案例和没有错误的案例之间的区别。这是我发现的:

  • 当它工作时,使用 TLSv1.2 或 1.3,当它不工作时,它是 TLSv1
  • 当它不起作用时,DNS 查询会显示 cloudfront cname 重定向,但用于套接字的端点匹配重定向

  • 基于这些观察,我知道我的代码能够使用 TLSv1.3,并且我认为使用 TLSv1 是问题所在。所以我试图通过 asio::ssl::context::tlsv13_client 强制 asio 对 TLS 使用 > 1 的版本。创建上下文时,或添加 asio::ssl::context::no_tlsv1到 set_options,但 wireshark 仍然显示使用了 TLSv1 协议(protocol)。
    对于第二点,我对网络东西不太熟悉,所以我不确定我能得出什么结论,或者即使它与问题相关。
    最小的工作示例:
    #include <asio.hpp>
    #include <asio/ssl.hpp>

    #include <iostream>

    int main(int argc, char* argv[])
    {
    try
    {
    asio::io_context io_context;
    asio::ip::tcp::resolver resolver(io_context);
    asio::ip::tcp::resolver::results_type endpoints = resolver.resolve("google.com", "https"); //not working with "api.minecraftservices.com" for example

    asio::ssl::context ctx(asio::ssl::context::sslv23); // also tried tlsv13_client to force v1.3, without success
    ctx.set_default_verify_paths();
    ctx.set_options(asio::ssl::context::default_workarounds | asio::ssl::context::verify_none);

    asio::ssl::stream<asio::ip::tcp::socket> socket(io_context, ctx);
    socket.set_verify_mode(asio::ssl::verify_none);
    socket.set_verify_callback([](bool, asio::ssl::verify_context&) {return true; });
    asio::connect(socket.lowest_layer(), endpoints);
    socket.handshake(socket.client);
    }
    catch (const std::exception& e)
    {
    std::cout << e.what() << std::endl;
    return -1;
    }

    return 0;
    }

    最佳答案

    您需要更具体地了解您尝试连接的服务器:
    Live On Coliru

    #include <boost/asio.hpp>
    #include <boost/asio/ssl.hpp>
    #include <iostream>

    namespace ssl = boost::asio::ssl;
    using boost::asio::ip::tcp;

    int main() {
    try {
    boost::asio::io_context io_context;
    tcp::resolver resolver(io_context);

    ssl::context ctx(ssl::context::sslv23); // also tried tlsv13_client to
    // force v1.3, without success
    ctx.set_default_verify_paths();
    ctx.set_options(ssl::context::default_workarounds |
    ssl::context::verify_none);

    ssl::stream<tcp::socket> socket(io_context, ctx);
    socket.set_verify_mode(ssl::verify_none);
    socket.set_verify_callback([](auto&&...) { return true; });

    #ifndef COLIRU
    connect(socket.lowest_layer(), resolver.resolve("d7uri8nf7uskq.cloudfront.net", "https"));
    #else
    socket.lowest_layer().connect({boost::asio::ip::address_v4::from_string("65.9.84.220"), 443});
    #endif
    std::cout << "Connected to " << socket.lowest_layer().remote_endpoint() << "\n";
    socket.handshake(socket.client);
    } catch (std::exception const& e) {
    std::cout << e.what() << std::endl;
    return -1;
    }
    }
    打印
    Connected to 65.9.84.220:443
    更新
    事实上,使用 api.minecraftservices.com:443 确实可以打印
    Connected to 65.9.78.95:443
    handshake: wrong version number (SSL routines, ssl3_get_record) [asio.ssl:336130315]
    原来你需要 SNI :
    SSL_set_tlsext_host_name(socket.native_handle(), "api.minecraftservices.com");
    然后它就可以工作了(使用不同的 IP 分辨率)
    Connected to 65.9.78.23:443

    关于c++ - 在与 Asio 和 OpenSSL 握手期间,*某些*网站上出现错误的版本号错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71080735/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com