Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;将TCP套接字转换为BIO(OpenSSL)_C++_Sockets_Ssl_Openssl - Fatal编程技术网

C++ C++;将TCP套接字转换为BIO(OpenSSL)

C++ C++;将TCP套接字转换为BIO(OpenSSL),c++,sockets,ssl,openssl,C++,Sockets,Ssl,Openssl,首先,我确实搜索了我的问题,但要准确地找到这个主题的答案并不容易 我编写了一个小型的C++程序,通过SoCKS5代理连接到HTTP网站。这一切都很好。现在我想连接到HTTPS网站,这会造成一些麻烦 问题是我不能直接创建BIO*并连接到SOCKS5代理,我需要先使用未加密的套接字执行SOCKS5协议,然后将其转换为BIO*。我说的对吗 因此,我截取了这段代码,用于正常的TCP->SOCKS5->网站内容: SOCKS5_Greeting_Response socks_gresp; SOCKS5_C

首先,我确实搜索了我的问题,但要准确地找到这个主题的答案并不容易

我编写了一个小型的C++程序,通过SoCKS5代理连接到HTTP网站。这一切都很好。现在我想连接到HTTPS网站,这会造成一些麻烦

问题是我不能直接创建BIO*并连接到SOCKS5代理,我需要先使用未加密的套接字执行SOCKS5协议,然后将其转换为BIO*。我说的对吗

因此,我截取了这段代码,用于正常的TCP->SOCKS5->网站内容:

SOCKS5_Greeting_Response socks_gresp;
SOCKS5_Command_Response socks_cresp;
int sock = createSocket();

socketConnect(sock, "127.0.0.1", 9050);

socks_gresp = socketWriteSOCKS5Greeting_TOR(sock);

if(socks_gresp.Version == 5){

    std::cout << "[i] Version match!" << std::endl;

}

socks_cresp = SOCKS5_Connect(sock, get_IPv4("www.google.de"), 80);

if(socks_cresp.Reply == 0){

    std::cout << "[i] Connection success!" << std::endl;

}
else if(socks_cresp.Reply == 1){

    std::cout << "[i] General server error" << std::endl;

}
else if(socks_cresp.Reply == 3){

    std::cout << "[i] Network not reachable" << std::endl;

}
else if(socks_cresp.Reply == 5){

    std::cout << "[i] Connection refused!" << std::endl;

}
如果出现错误,我的SSL_write()将输出<0,否则字节将被发送。这是我的输出:

[i] Version match!
[i] Connection success!
[i] SSL Write: 191
F

我应该在那里看到HTML源代码或HTTP响应,而不是“F”。。我很确定我在创作这本传记时做了一些错误的事情,但我不知道是什么。这里的任何人都可以?

简短回答:不要使用OpenSSL BIO,而是使用。

您所要求的与其他需要开始未加密然后稍后升级到SSL/TLS的情况没有什么不同,例如SMTP上的
STARTTLS
。是的,有很多方法可以通过OpenSSL的BioAPI实现这一点

OpenSSL有自己的
SSL\u write()
SSL\u read()
函数,这些函数需要
SSL*
作为输入。您正在调用
SSL\u write()
SSL\u read()
函数,这些函数将
BIO*
作为输入,并直接读取/写入
std::string
值。显然,您已经用自定义函数重载了本机函数。事实上,您正在传递一个
BIO*
,这让我认为您可能在这些函数中调用
BIO\u write()
BIO\u read()
。使用
SSL\u set\u bio()
时,需要使用本机
SSL\u write()
SSL\u read()
函数直接使用
SSL*
进行读/写。在内部,他们将根据需要为较低级别的插座I/O使用相关的
BIO*


也就是说,尽管上述方法可行,但这并不是在这种情况下使用BIO API的唯一方法。另一种方法是使用
BIO\u new\u ssl\u connect()
创建一个
BIO
链,该链由一个ssl/TLS
BIO
和一个连接在一起的套接字连接
BIO
组成。调用
BIO\u do\u connect()
连接SOCKS代理,然后使用
BIO\u find\u type(BIO\u type\u SOCKET)
从链中检索套接字
BIO*
,并在其上使用
BIO\u read()
BIO\u write()
根据需要执行未加密的SOCKS I/O。准备好后,在SSL/TLS
BIO*
上调用
BIO\u do\u handshake()
以启动SSL/TLS握手(它将通过已连接的套接字
BIO*
),然后使用
BIO\u read()
BIO\u write()
在SSL/TLS上
BIO*
根据需要执行加密的I/O。

OpenSSL BIO对于OP的要求非常有效。你必须知道如何使用它。当你似乎知道它的时候,为什么不告诉我呢?好吧,没错,但是curl文档更全面,而且你不必随身携带来执行SSL连接,所以我还是选择libcurl。更不用说OpenSSL的安全历史还有很多不尽如人意的地方。
[i] Version match!
[i] Connection success!
[i] SSL Write: 191
F