首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Boost Beast握手: sslv3警报握手失败错误

Boost Beast握手: sslv3警报握手失败错误
EN

Stack Overflow用户
提问于 2019-12-07 10:01:09
回答 1查看 2.5K关注 0票数 3

我正在使用Boost Beast连接到Web套接字服务器,但我一直收到一个错误

代码语言:javascript
运行
复制
Resolving push-private.kucoin.com:443...
Performing SSL handshake...
terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>'
  what():  handshake: sslv3 alert handshake failure
Aborted (core dumped)
代码语言:javascript
运行
复制
#include <iostream>
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <string>
#include "root_certificates.hpp"

using namespace std;

namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl;       // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>

int main() {
    // for a new token, make a POST request to https://api.kucoin.com/api/v1/bullet-public
    const auto token = "2neAiuYvAU61ZDXANAGAsiL4-iAExhsBXZxftpOeh_55i3Ysy2q2LEsEWU64mdzUOPusi34M_wGoSf7iNyEWJ3XLno4x6QqZaEm7Ya4KUfToabAuI1Do9tiYB9J6i9GjsxUuhPw3BlrzazF6ghq4L2ls_Ixv_6qQ8ZRhwt_6WmM=.ianWlE3VQZogjKRmJ-tpyg==";

    auto const host = "push-private.kucoin.com";
    auto const port = "443";
    auto const text = "hello world";

    // The io_context is required for all I/O
    net::io_context ioc;

    // The SSL context is required, and holds certificates
    boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);

    ctx.set_options(
            boost::asio::ssl::context::default_workarounds
                | boost::asio::ssl::context::no_sslv2
                | boost::asio::ssl::context::no_sslv3
    ); 

    ctx.set_default_verify_paths();

    // This holds the root certificate used for verification
    load_root_certificates(ctx);

    // These objects perform our I/O
    tcp::resolver resolver{ioc};
    websocket::stream<beast::ssl_stream<tcp::socket>> ws{ioc, ctx};

    // Look up the domain name
    cout << "Resolving " << host << ":" << port << "..." << endl;
    auto const results = resolver.resolve(host, port);

    // Make the connection on the IP address we get from a lookup
    net::connect(ws.next_layer().next_layer(), results.begin(), results.end());

    // Perform the SSL handshake
    cout << "Performing SSL handshake..." << endl;
    ws.next_layer().handshake(ssl::stream_base::client);

    // Set a decorator to change the User-Agent of the handshake
    ws.set_option(websocket::stream_base::decorator([](websocket::request_type& req){
        req.set(http::field::user_agent,
            std::string(BOOST_BEAST_VERSION_STRING) +
                " websocket-client-coro");
    }));

    // Perform the websocket handshake
    cout << "Performing the websocket handshake..." << endl;
    ws.handshake(host, "/endpoint");

    // Send the message
    cout << "Sending '" << text << "'..." << endl;
    ws.write(net::buffer(std::string(text)));

    // This buffer will hold the incoming message
    beast::flat_buffer buffer;

    // Read a message into our buffer
    cout << "Waiting for web socket server to respond..." << endl;
    ws.read(buffer);

    // Close the WebSocket connection
    ws.close(websocket::close_code::normal);

    // The make_printable() function helps print a ConstBufferSequence
    cout << "This is the data received from the server:" << endl;
    std::cout << beast::make_printable(buffer.data()) << std::endl;

    return 0;
}

取自ssl.cpp的例子

我查看了类似于Boost asio获得与客户端证书sslv3握手失败的其他线程,这些线程建议添加ctx.set_options,我也尝试过这样做,但我也得到了相同的错误。

汇编选项:

代码语言:javascript
运行
复制
g++ -std=c++17 test.cpp -l boost_system -l crypto -l ssl -pthread  && ./a.out

gcc版9.1.0 (Ubuntu 9.1.0-2 ubuntu2~19.04)

如果有任何建议,我们将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-07 10:31:15

服务器需要SNI扩展,否则它不知道您要连接到哪个主机,因此不知道将哪个证书发回给您,因此它中止了握手。如果您在浏览器中转到https://99.86.115.35/,您可以看到同样的问题,它将显示一些SSL错误。

解决方案是告诉OpenSSL您要连接到的主机名:

代码语言:javascript
运行
复制
if(! SSL_set_tlsext_host_name(stream.native_handle(), host))
{
   boost::system::error_code ec{static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category()};
   throw boost::system::system_error{ec};
}

有关完整示例,请参见ssl.cpp

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59224873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档