C++将TCP套接字转换为BIO(OpenSSL)
C++ convert TCP Socket to BIO (OpenSSL)
首先,我确实搜索了我的问题,但要找到这个主题的答案并不容易。
我写了一个小型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;
}
之后我可以读/写/从袜子,我不想发布所有子功能,因为它会太多......
好吧,我在这里阅读:链接 1 我应该使用BIO_new_socket()
和SSL_set_bio()
我在这里找到了一个截取的代码:链接 2
所以这是我当前的代码截取,试图将 TCP 套接字转换为 BIO*(没有所有错误处理的东西,我在一切正常时包括它(:
SSL_library_init();
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"), 443);
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;
}
//--
BIO* sslsock = BIO_new_socket(sock, BIO_NOCLOSE);
SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_load_verify_locations(ctx, "/path/to/cacert.pem", NULL);
SSL* ssl = SSL_new(ctx);
SSL_set_bio(ssl, sslsock, sslsock);
std::cout << "[i] SSL Write: " << SSL_write(sslsock, generate_basic_GET_request("www.google.de","Mozilla","")) << std::endl;
std::cout << SSL_read(sslsock) << std::endl;
SSL_Close_Connection(sslsock);
//--
closeSocket(sock);
我的 SSL_write(( 将在错误时打印出 <0,否则字节发送。这是我的输出:
[i] Version match!
[i] Connection success!
[i] SSL Write: 191
F
而不是"F",我应该在那里看到HTML源代码或HTTP响应。我很确定我在创建 BIO* 时做了一些错误的事情,但我说不出是什么。这里有人可以吗?
您所要求的与其他需要启动未加密然后稍后升级到SSL/TLS的情况没有什么不同,例如在SMTP上STARTTLS
。 所以,是的,有一些方法可以通过OpenSSL的BIO API来实现这一点。
OpenSSL有自己的SSL_write()
和SSL_read()
函数,需要SSL*
作为输入。 您正在调用SSL_write()
和SSL_read()
函数,这些函数将BIO*
作为输入,并直接读取/写入std::string
值。 因此,您显然已经使用自定义函数重载了本机函数。 您传递BIO*
的事实使我认为您可能在这些函数中调用BIO_write()
和BIO_read()
。 使用 SSL_set_bio()
时,需要使用本机 SSL_write()
和 SSL_read()
函数直接与SSL*
一起读/写。 在内部,他们将根据需要将关联的BIO*
用于较低级别的套接字 I/O。
话虽如此,虽然上述方法有效,但它也不是在这种情况下使用 BIO API 的唯一方法。 另一种方法是使用BIO_new_ssl_connect()
创建一个BIO
链,该链由SSL/TLS BIO
和链接在一起的套接字连接BIO
组成。 调用 BIO_do_connect()
连接到 SOCKS 代理,然后使用 BIO_find_type(BIO_TYPE_SOCKET)
从链中检索套接字BIO*
,并根据需要在其上使用BIO_read()
和BIO_write()
来执行未加密的 SOCKS I/O。 准备就绪后,在 SSL/TLS BIO*
上调用 BIO_do_handshake()
以启动 SSL/TLS 握手(将通过已连接的套接字BIO*
(,然后在 SSL/TLS BIO*
上使用BIO_read()
和BIO_write()
根据需要执行加密的 I/O。
简短的回答:不要使用OpenSSL BIO而使用libcurl。
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 如何在openssl-ecc中获取十六进制格式的私钥
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 如何在OpenSSL中从configuration.h.in获取configuration.h
- OpenSSL TLS服务器-使用客户端证书白名单
- 通过 Openssl 命令行加密,通过 c++ 解密
- 使用已使用 java 编码的 openssl 解码数据
- OpenSSL没有共享密码
- OpenSSL 解密功能无法正常工作
- OpenSSL BIO and SSL_read
- OpenSSL:将不安全的BIO提升为安全
- "400 Bad request"使用 OpenSSL BIO 进行请求时
- base64 decode with openssl BIO block by block
- 如何正确处理OpenSSL错误(BIO)
- 使用OpenSSL BIO实现无阻塞I/O
- OpenSSL - 通过内存将 X509* x509 转换为 file-BIO*
- 如何让使用阻塞BIO的OpenSSL服务器干净地关闭
- 使用OpenSSL库在C++中将BIO*转换为PKCS7*
- C++将TCP套接字转换为BIO(OpenSSL)
- 指示OpenSSL在设置新BIO时不释放BIO对象