opensssl BIO方式https客户端

这篇具有很好参考价值的文章主要介绍了opensssl BIO方式https客户端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

废话不多说,代码中使用了两种https客户端的实现方式。文章来源地址https://www.toymoban.com/news/detail-804233.html




#include <windows.h>
#include <WinSock.h>

#pragma comment(lib,"ws2_32.lib")
#include "../include/openssl\ssl.h"
#include "../include/openssl\err.h"


#pragma comment ( lib, "../lib/libeay32.lib" )
#pragma comment ( lib, "../lib/ssleay32.lib" )


#define HTTPS_PORT 443


DWORD BIOSendRecvData(sockaddr_in stBaiduPassPortAddr,char * pSendData,int iSendSize,char * pRecvData,int iRecvSize)
{
	//ERR_load_crypto_strings();
	//ERR_load_SSL_strings();
	//OPENSSL_add_all_algorithms_noconf();

	//如果系统平台不支持自动进行随机数种子的设置,这里应该进行设置(seed PRNG)
	SSL_CTX * ctxClient = SSL_CTX_new(SSLv3_client_method());

	//通常应该在这里设置一些验证路径和模式等,因为这里没有设置,所以该例子可以跟使用任意CA签发证书的任意服务器建立连接
	BIO * stBio = BIO_new_ssl_connect(ctxClient);

	SSL * sslClient = FALSE;
	int iRet = BIO_get_ssl(stBio,&sslClient);
	if(sslClient == FALSE)
	{
		fprintf(stderr,"Can't locate SSL pointer\n");
		//ERR_print_errors_fp(stderr);
		//SSL_free(sslClient);
		SSL_CTX_free(ctxClient);
		BIO_free_all(stBio);
		return FALSE;
	}
	/* 不需要任何重试请求*/
	iRet = SSL_set_mode(sslClient,SSL_MODE_AUTO_RETRY);
	//这里你可以添加对SSL的其它一些设置

	char szBioConnectAddrFormat[] = "%s:%u";
	char szBioConnectAddr[64];
	int iLen = wsprintfA(szBioConnectAddr,szBioConnectAddrFormat,inet_ntoa(stBaiduPassPortAddr.sin_addr),HTTPS_PORT);
	iRet = BIO_set_conn_hostname(stBio,szBioConnectAddr);		//"passport.baidu.com"
	//BIO * out=BIO_new_fp(stdout,BIO_NOCLOSE);
	if(BIO_do_handshake(stBio)<=0)
	{
		//SSL_free(sslClient);
		SSL_CTX_free(ctxClient);
		fprintf(stderr,"Error connecting to server\n");
		ERR_print_errors_fp(stderr);
		return FALSE;
	}

	X509 * stCert = SSL_get_peer_certificate(sslClient);
	char * strServerName = X509_NAME_oneline(X509_get_subject_name(stCert),0,0);
	OPENSSL_free(strServerName);
	strServerName = X509_NAME_oneline(X509_get_issuer_name(stCert),0,0);
	OPENSSL_free(strServerName);
	X509_free(stCert);

	iRet = BIO_write(stBio,pSendData,iSendSize);
	if (iRet <= 0)
	{
		//SSL_free(sslClient);
		SSL_CTX_free(ctxClient);
		BIO_free_all(stBio);
		return FALSE;
	}
	char * pRecvPtr = pRecvData;
	iRet = BIO_read(stBio,pRecvPtr,iRecvSize);
	if (iRet <= 0)
	{
		//SSL_free(sslClient);
		SSL_CTX_free(ctxClient);
		BIO_free_all(stBio);
		return FALSE;
	}
	while(iRet == 1)
	{
		pRecvPtr ++;
		iRet = BIO_read(stBio,pRecvPtr,iRecvSize);
	}

	if (iRet > 0)
	{
		*(pRecvPtr + iRet) = 0;
	}

	BIO_free_all(stBio);

	SSL_CTX_free(ctxClient);
	//SSL_free(sslClient);
	//BIO_free(out);
	return TRUE;
}










DWORD SendAndRecvHttpsPacket(sockaddr_in stBaiduPassPortAddr,char * pSendData,int iSendSize,char * pRecvData,int iRecvSize)
{
	SOCKET sockClient = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (sockClient == INVALID_SOCKET)
	{
		return FALSE;
	}

	int iRet = connect(sockClient,(sockaddr*)&stBaiduPassPortAddr,sizeof(sockaddr_in));
	if (iRet == INVALID_SOCKET)
	{
		closesocket(sockClient);
		return FALSE;
	}

	SSL_CTX * pctxClient = SSL_CTX_new( SSLv23_client_method() );
	if (pctxClient == 0)
	{
		iRet = GetLastError();
		closesocket(sockClient);
		return FALSE;
	}

	SSL * pSSLClient = SSL_new(pctxClient);
	if (pSSLClient == 0)
	{
		closesocket(sockClient);
		return FALSE;
	}

	iRet = SSL_set_fd(pSSLClient,sockClient);
	if (iRet <= 0)
	{
		iRet = GetLastError();
		closesocket(sockClient);
		return FALSE;
	}

	iRet = SSL_connect(pSSLClient);
	if (iRet <= 0)
	{
		iRet = GetLastError();
		//return FALSE;
	}

	iRet = SSL_write(pSSLClient,pSendData,iSendSize);
	if (iRet <= 0)
	{
		iRet = GetLastError();
		//return FALSE;
	}

	char * pRecvBuf = pRecvData;
	int iSize = iRecvSize;
	do
	{
		iRet = SSL_read(pSSLClient,pRecvBuf,1);
		if (iRet > 0)
		{
			pRecvBuf ++;
			iSize --;
		}
	} while (iRet > 0);
	*pRecvBuf = 0;

	SSL_free(pSSLClient);
	SSL_CTX_free(pctxClient);
	closesocket(sockClient);
	return (pRecvBuf - pRecvData);
}



/*
DWORD BIOServerSample()
{
    BIO *sbio, *bbio, *acpt, *out;
    int len;
    char tmpbuf[1024];
    SSL_CTX *ctx;
    SSL *ssl;

    ERR_load_crypto_strings();
    ERR_load_SSL_strings();
    OpenSSL_add_all_algorithms();

    //Might seed PRNG here 

    ctx = SSL_CTX_new(SSLv23_server_method());

    if (!SSL_CTX_use_certificate_file(ctx,"server.pem",SSL_FILETYPE_PEM)
           || !SSL_CTX_use_PrivateKey_file(ctx,"server.pem",SSL_FILETYPE_PEM)
           || !SSL_CTX_check_private_key(ctx)) {

           fprintf(stderr, "Error setting up SSL_CTX\n");
           ERR_print_errors_fp(stderr);
           return 0;
    }

	//Might do other things here like setting verify locations and
	//DH and/or RSA temporary key callbacks
     

    // New SSL BIO setup as server 
    sbio=BIO_new_ssl(ctx,0);

    BIO_get_ssl(sbio, &ssl);

    if(!ssl) {
      fprintf(stderr, "Can't locate SSL pointer\n");
      // whatever ... 
    }

    // Don't want any retries 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    // Create the buffering BIO 

    bbio = BIO_new(BIO_f_buffer());

    //Add to chain 
    sbio = BIO_push(bbio, sbio);

    acpt=BIO_new_accept("433");

   //  By doing this when a new connection is established
   //  we automatically have sbio inserted into it. The
   //  BIO chain is now 'swallowed' by the accept BIO and
   //  will be freed when the accept BIO is freed.
     

    BIO_set_accept_bios(acpt,sbio);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);

    // Setup accept BIO 
    if(BIO_do_accept(acpt) <= 0) {
           fprintf(stderr, "Error setting up accept BIO\n");
           ERR_print_errors_fp(stderr);
           return 0;
    }

    // Now wait for incoming connection 
    if(BIO_do_accept(acpt) <= 0) {
           fprintf(stderr, "Error in connection\n");
           ERR_print_errors_fp(stderr);
           return 0;
    }

    // We only want one connection so remove and free
    // accept BIO
    //

    sbio = BIO_pop(acpt);

    BIO_free_all(acpt);

    if(BIO_do_handshake(sbio) <= 0) {
           fprintf(stderr, "Error in SSL handshake\n");
           ERR_print_errors_fp(stderr);
           return 0;
    }

    BIO_puts(sbio, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n");
    BIO_puts(sbio, "\r\nConnection Established\r\nRequest headers:\r\n");
    BIO_puts(sbio, "--------------------------------------------------\r\n");

    for(;;) {
           len = BIO_gets(sbio, tmpbuf, 1024);
           if(len <= 0) break;
           BIO_write(sbio, tmpbuf, len);
           BIO_write(out, tmpbuf, len);
           // Look for blank line signifying end of headers
           if((tmpbuf[0] == '\r') || (tmpbuf[0] == '\n')) break;
    }

    BIO_puts(sbio, "--------------------------------------------------\r\n");
    BIO_puts(sbio, "\r\n");

    // Since there is a buffering BIO present we had better flush it 
    BIO_flush(sbio);

    BIO_free_all(sbio);
	return TRUE;
}
*/





int __stdcall WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd ){

	WSAData wsa;

	int ret = WSAStartup(0x0202,&wsa);
	if (ret )
	{
		return FALSE;
	}


	SSL_library_init( );			
	SSL_load_error_strings( );
	OpenSSL_add_all_algorithms();

	char szdata[0x4000];
	for (int i =0;i < sizeof(szdata); i ++)
	{
		szdata[i] = 'a';
	}
	szdata[0] = '/';
	szdata[1] = 0;

	hostent * lphost= gethostbyname("www.baidu.com");
	DWORD lpip = *(DWORD*)(lphost->h_addr_list);
	DWORD ip= *(DWORD*)lpip;

	sockaddr_in sa = {0};
	sa.sin_family = AF_INET;
	sa.sin_port = ntohs(443);
	sa.sin_addr.S_un.S_addr = ip;


	char szrecv[0x4000];
	ret=BIOSendRecvData(sa,szdata, lstrlenA(szdata),szrecv, sizeof(szdata));
	//ret=SendAndRecvHttpsPacket(sa,szdata,0x10000,szrecv,0x10000);

	// 	SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	// 	if (s == INVALID_SOCKET)
	// 	{
	// 		return FALSE;
	// 	}

	return TRUE;
}

到了这里,关于opensssl BIO方式https客户端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ESP8266-Arduino网络编程实例-HTTPS客户端数据请求

    超文本传输协议安全 (HTTPS) 是 HTTP的安全版本,HTTP 是用于在 Web 浏览器和网站之间发送数据的主要协议。HTTPS 经过加密,以提高数据传输的安全性。当用户传输敏感数据(例如通过登录银行账户、电子邮件服务或健康保险提供商)时,这一点尤其重要。 从技术上来讲,HTTPS

    2023年04月08日
    浏览(62)
  • java获取客户端ip的正确方式

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 如果使用了反向代理软件,将http://192.168.1.110:2046/的URL反向代理为http://www.abc.com/的URL时,用reques

    2024年02月05日
    浏览(33)
  • Windows如何部署TortoiseSVN客户端

    TortoiseSVN是一个开源的版本控制系统,它与Apache Subversion(SVN)集成在一起,提供了一个用户友好的界面,方便用户进行版本控制和团队协作,广泛应用于软件开发和项目管理领域。 TortoiseSVN主要用于管理项目代码的版本控制,可以追踪文件的修改、记录变更历史、解决冲突等

    2024年01月21日
    浏览(42)
  • 客户端脚本安全

    a.了解web安全测试的基本知识 b.掌握前端的脚本安全知识,了解基本的前端安全测试条目,如同源策略、xss攻击测试、CSRF测试、点击劫持测试 c.webinsepct nessus 绿盟扫描 数据流 输入输出 同源策略 同源策略 是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本

    2024年02月04日
    浏览(33)
  • Windows10系统开启 Telnet客户端 功能

    1、应用场景 在实际工作中,经常有查看机器端口连通性的场景(主要为了确认某台机器上的服务是否正常,比如:查看的端口 9091) 如下状态说明telnet 端口是通的 Ctrl + ] ,退出Telnet连接, quit 命令退出Telnet客户端 2、开启方式 Win10系统与Win7、Win8系统相比,默认关闭了 Telne

    2024年02月08日
    浏览(39)
  • Kubernetes客户端认证——基于CA证书的双向认证方式

    Kubernetes集群的访问权限控制由API Server负责,API Server的访问权限控制由身份验证(Authentication)、授权(Authorization)和准入控制(Admission control)三个步骤组成,这个三个步骤是按序进行的(详细介绍请参见《(转)使用kubectl访问Kubernetes集群时的身份验证和授权》)。 其中身份验证

    2023年04月10日
    浏览(25)
  • Java 客户端调用 WebService 接口的一种方式

      通过SoapUI创建一个SOAP Project;   项目名称自定义,WSDL地址维护WebService接口地址。点击OK即可   项目创建完成后,展开WebService项,可以看到具体的接口,打开接口下的Request,右侧面板Form标签下可以清晰的看到请求入参,点击Submit请求按钮可以看到Overview标签下的响应结

    2024年01月18日
    浏览(36)
  • Windows运维终端安装syslog日志客户端

    作用:通过syslog协议记录传输 Windows的日志到日志审计服务器。 下载nxlog。 下载地址: (https://nxlog.co/products/all/download) 安装下载完成的nxlog-ce.msi点击Next(以下以nxlog-ce-2.11.2190.msi版本安装为例)。 选择默认安装位置。 4. 点击Install选择安装。 5. 点击Finish完成安装。 6. 修改配置

    2024年02月13日
    浏览(32)
  • IT运维:Windows常用的命令行客户端

    对于IT运维人员来说,和命令打交道是必不可少的事情,拥有一个好用的CMD命令行工具,对提升效率是非常有必要的,今天给大家分享Windows常用的命令行客户端,希望对大家能有所帮助! PowerShell 是一个由微软开发的命令行工具,用于在 Windows 系统上执行命令和运行脚本。它

    2024年02月03日
    浏览(53)
  • Windows后台运行并启动Frpc客户端界面

    frp搭建内网穿透可以看我另外一篇 启动frps服务端 3.1.先去下载NSSM服务。 地址:http://www.nssm.cc/download NSSM 是一个服务封装程序,它可以将普通exe程序封装成服务,使之像windows服务一样运行。 我的是win64,找对应的系统 然后把nssm.exe这个文件放到frpc同一个目录上 3.2.启动nssm 先以管

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包