【发布时间】:2022-07-07 20:41:17
【问题描述】:
我正在尝试编写程序来与服务器通信。 我正在使用 C++、boost::asio、TCP 和 OpenSSl 来发送和接收消息。
- C++ : 20
- 提升:1.78
- OpenSSL:1.1.1p
- 窗户
- Visual Studio 2022
我的问题是收到的消息总是加密的。 我无法正确阅读。 boost不自动解加密吗?
#if defined(_WIN32)
#pragma comment(lib, "crypt32.lib")
#endif
#include <cstdint>
#include <functional>
#include <iostream>
#include <string>
#include <string.h>
#include <boost/asio.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/bind/bind.hpp>
#include <boost/chrono.hpp>
#include <boost/json.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/thread.hpp>
#if defined(_WIN32)
#include <windows.h>
#include <wincrypt.h>
#endif
using boost_query = boost::asio::ip::tcp::resolver::query;
using boost_resolver = boost::asio::ip::tcp::resolver;
using boost_endpoint = boost::asio::ip::tcp::endpoint;
using boost_context = boost::asio::ssl::context;
using boost_socket = boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
using boost_error = boost::system::errc::errc_t;
constexpr std::uint32_t MAX_BUFFER_RECV{ 1024u };
boost::system::error_code ec{};
boost::asio::io_service ioService{};
boost_context context{ boost_context::tlsv12 };
boost_socket socketSSL{ ioService, context };
char recvBuffer[MAX_BUFFER_RECV]{ 0, };
std::string host{};
std::int32_t port{};
bool isSecu{};
static bool onVerifySSL(
bool preverified,
boost::asio::ssl::verify_context& verifyContext)
{
char subjectName[256]{};
auto* cert{
X509_STORE_CTX_get_current_cert(verifyContext.native_handle()) };
if (nullptr == cert)
{
std::cerr << "Certificat is uncorrect." << std::endl;
return false;
}
auto x509Name{ X509_get_subject_name(cert) };
auto name{ X509_NAME_oneline(x509Name, subjectName, 256) };
if (nullptr != name) { std::cout << "certificat: " << name << std::endl; }
return true;
}
static void onSend(
boost::system::error_code const& ec,
std::size_t bytes)
{
std::cout << "Sent : " << ec.message() << std::endl;
if (boost_error::success == ec)
{
std::cout << "Sent success !" << std::endl;
}
}
static void onReceive(
boost::system::error_code const& ec,
std::size_t bytes)
{
std::cout << "Receive : " << ec.message() << std::endl;
if (boost_error::success == ec)
{
char rxBuffer[MAX_BUFFER_RECV]{};
std::memset(rxBuffer, 0, MAX_BUFFER_RECV);
std::memcpy(rxBuffer, recvBuffer, bytes);
std::cout
<< "Receive " << bytes << " bytes\n"
<< "data[" << rxBuffer << "]\n"
<< "data[";
for (auto i{ 0 }; i < bytes; ++i)
{
std::cout << rxBuffer[i];
}
std::cout << "]" << std::endl;
std::memset(recvBuffer, 0, MAX_BUFFER_RECV);
}
else
{
std::cerr << "Fail receive" << std::endl;
}
}
static void asyncRead()
{
socketSSL.next_layer().async_receive(
boost::asio::buffer(recvBuffer, MAX_BUFFER_RECV),
boost::bind(
onReceive,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
static void asyncWrite()
{
boost::json::object root;
root["id"] = 1;
root["method"] = "mining.subscribe";
root["params"] = boost::json::array{ "Test/1.0", "EthereumStratum/1.0.0" };
std::ostringstream oss;
oss << root;
std::string str{ oss.str() + "\n" };
socketSSL.next_layer().async_send(
boost::asio::buffer(str.c_str(), str.size()),
boost::bind(
&onSend,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
static bool applySecu()
{
if (false == isSecu)
{
socketSSL.set_verify_mode(boost::asio::ssl::verify_none);
return true;
}
socketSSL.set_verify_mode(boost::asio::ssl::verify_peer);
socketSSL.set_verify_callback(
boost::bind(
&onVerifySSL,
std::placeholders::_1,
std::placeholders::_2));
#if defined(_WIN32)
auto certStore{ CertOpenSystemStore(0, "ROOT") };
if (certStore == nullptr)
{
std::cerr << "Certifcat Store \"ROOT\" was nout found !" << std::endl;
return false;
}
auto* store{ X509_STORE_new() };
PCCERT_CONTEXT certContext{ nullptr };
while (nullptr != (certContext = CertEnumCertificatesInStore(certStore, certContext)))
{
auto* x509
{
d2i_X509
(
nullptr,
(const unsigned char**)&(certContext->pbCertEncoded),
certContext->cbCertEncoded
)
};
if (nullptr != x509)
{
X509_STORE_add_cert(store, x509);
X509_free(x509);
}
}
CertFreeCertificateContext(certContext);
CertCloseStore(certStore, 0);
SSL_CTX_set_cert_store(context.native_handle(), store);
#endif
return true;
}
static bool resolveHost()
{
auto const address{ boost::asio::ip::address::from_string(host, ec) };
if (boost_error::success != ec)
{
std::cout << "resolving " << host << ":" << port << std::endl;
boost_resolver resolver{ ioService };
boost_query query{ host, std::to_string(port) };
auto endpoints{ resolver.resolve(query, ec) };
if (boost_error::success != ec)
{
std::cerr << "can not resolve " << host << ":" << port << std::endl;
return false;
}
boost::asio::connect(socketSSL.next_layer(), endpoints, ec);
if (boost_error::success != ec)
{
std::cerr << "can not connect to " << host << ":" << port << std::endl;
return false;
}
}
else
{
boost_endpoint endpoint{
address,
static_cast<boost::asio::ip::port_type>(port) };
socketSSL.next_layer().connect(endpoint, ec);
if (boost_error::success != ec)
{
std::cerr << "can not connect to " << host << ":" << port << std::endl;
return false;
}
}
return true;
}
static bool connectToServer()
{
std::cout << "Connection with " << host << ":" << port << " was etablished" << std::endl;
socketSSL.next_layer().set_option(
boost::asio::socket_base::keep_alive(true));
socketSSL.next_layer().set_option(
boost::asio::ip::tcp::no_delay(true));
if (true == isSecu)
{
std::cout << "handshake" << std::endl;
socketSSL.handshake(boost::asio::ssl::stream_base::client, ec);
if (boost_error::success != ec)
{
std::cerr << "Fail handshake" << std::endl;
return false;
}
}
return true;
}
int main(int argc, char** argv)
{
if (argc != 4)
{
std::cerr << "USAGE : ./pool_client <IP|DNS> <PORT> <IS_SECU>" << std::endl;
return 1;
}
host.assign(argv[1]);
port = std::atoi(argv[2]);
isSecu = (std::atoi(argv[3]) == 1);
std::cout
<< "Starting Tool Pool Client" << "\n"
<< "Connection " << host << ":" << port << "\n"
<< "SSL : " << std::boolalpha << isSecu << std::noboolalpha << std::endl;
if (false == applySecu()) { return 1; }
resolveHost();
if (false == connectToServer()) { return 1; }
asyncWrite();
asyncRead();
auto runService = boost::thread{
boost::bind(&boost::asio::io_service::run, &ioService) };
runService.join();
return 0;
}
tool_pool_client rvn.2miners.com 6060 0
输出 :
当我在没有 SSL 的情况下运行我的程序时,我可以读取接收到的数据。
Starting Tool Pool Client
Connection rvn.2miners.com:6060
SSL : false
resolving rvn.2miners.com:6060
Connection with rvn.2miners.com:6060 was etablished
Sent : Operation success
Sent success !
Receive : Operation success
Receive 49 bytes
data[{"id":1,"result":["00f59158","6a"],"error":null}
]
data[{"id":1,"result":["00f59158","6a"],"error":null}
]
当我使用 SSL 运行我的程序时,我无法读取收到的数据data[]。
tool_pool_client rvn.2miners.com 16060 1
输出:
Starting Tool Pool Client
Connection rvn.2miners.com:16060
SSL : true
resolving rvn.2miners.com:16060
Connection with rvn.2miners.com:16060 was etablished
handshake
certificat: /C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority
certificat: /C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Domain Validation Secure Server CA
certificat: /CN=*.2miners.com
Sent : Operation success
Sent success !
Receive : Operation success
Receive 62 bytes
data[§♥♥]
data[§♥♥→☺▀ò¡7%█¬Ø[▄>ÿ┤╔æ¢ÂD§♥♥→☻É8fÒl«ªé6í┐ýZ→å{<»]
函数applySecu 在上下文中添加证书。
函数onReceive打印接收到的数据。
我的错误是什么?谢谢。
【问题讨论】:
-
向我们展示不起作用的代码。
-
不,是什么让您认为 Boost 可能拥有大量与密码学相关的协议的完整实现,您在 Boost 的文档中看到过类似的内容吗?看起来未显示的代码没有正确执行。
-
@user253751 i 链接代码:pastebin.fr/107966 函数
onReceive打印接收到的数据。 -
此处的所有问题都应在问题本身中以纯文本形式包含所有相关信息。链接可以随时停止工作,使问题变得毫无意义。无法复制/粘贴以图像形式显示的代码、数据或错误;或编辑或编译以供进一步研究和调查。你能edit这个问题,删除和替换所有链接和图像,并将所有相关信息作为纯文本吗?所有代码必须满足minimal reproducible example 的所有要求。你会在这里找到许多其他问题,minimal reproducible example,纯文本。请以它们为例说明您的问题应该是什么样子。
-
@s4oul boost 不会解密您的数据。对于 openssl 来说,这更像是一项工作。
标签: c++ ssl boost-asio