加速兽握手:sslv3 警报握手失败错误

Boost Beast handshake: sslv3 alert handshake failure error

本文关键字:失败 错误 加速 sslv3      更新时间:2023-10-16

我正在使用Boost Beast连接到Web Socket服务器,但不断收到错误

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)
#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;
}

取自 https://www.boost.org/doc/libs/1_70_0/libs/beast/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp 的例子

我查看了其他类似于客户端证书 sslv3 握手的 Boost asio GET 的线程,该线程建议添加ctx.set_options,我也尝试过,但我收到同样的错误。

编译选项:

g++ -std=c++17 test.cpp -l boost_system -l crypto -l ssl -pthread  && ./a.out

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

任何建议将不胜感激。

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

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

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};
}

有关完整示例,请参阅野兽http_client_sync_ssl.cpp