news 2026/7/15 16:06:05

ssl/https通信(opensssl接口)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ssl/https通信(opensssl接口)

废话不多说,代码中使用了两种https客户端的实现方式。

完整代码:https://github.com/satadriver/openssl-TLS_SSL-sample

#include<windows.h>#include<WinSock.h>#include"../include/openssl\ssl.h"#include"../include/openssl\err.h"#pragmacomment(lib,"ws2_32.lib")#pragmacomment(lib,"../lib/libeay32.lib")#pragmacomment(lib,"../lib/ssleay32.lib")#defineHTTPS_PORT443DWORDBIOSendRecvData(sockaddr_in stBaiduPassPortAddr,char*pSendData,intiSendSize,char*pRecvData,intiRecvSize){//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;intiRet=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);returnFALSE;}/* 不需要任何重试请求*/iRet=SSL_set_mode(sslClient,SSL_MODE_AUTO_RETRY);//这里你可以添加对SSL的其它一些设置charszBioConnectAddrFormat[]="%s:%u";charszBioConnectAddr[64];intiLen=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);returnFALSE;}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);returnFALSE;}char*pRecvPtr=pRecvData;iRet=BIO_read(stBio,pRecvPtr,iRecvSize);if(iRet<=0){//SSL_free(sslClient);SSL_CTX_free(ctxClient);BIO_free_all(stBio);returnFALSE;}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);returnTRUE;}DWORDSendAndRecvHttpsPacket(sockaddr_in stBaiduPassPortAddr,char*pSendData,intiSendSize,char*pRecvData,intiRecvSize){SOCKET sockClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sockClient==INVALID_SOCKET){returnFALSE;}intiRet=connect(sockClient,(sockaddr*)&stBaiduPassPortAddr,sizeof(sockaddr_in));if(iRet==INVALID_SOCKET){closesocket(sockClient);returnFALSE;}SSL_CTX*pctxClient=SSL_CTX_new(SSLv23_client_method());if(pctxClient==0){iRet=GetLastError();closesocket(sockClient);returnFALSE;}SSL*pSSLClient=SSL_new(pctxClient);if(pSSLClient==0){closesocket(sockClient);returnFALSE;}iRet=SSL_set_fd(pSSLClient,sockClient);if(iRet<=0){iRet=GetLastError();closesocket(sockClient);returnFALSE;}iRet=SSL_connect(pSSLClient);if(iRet<=0){iRet=GetLastError();returnFALSE;}iRet=SSL_write(pSSLClient,pSendData,iSendSize);if(iRet<=0){iRet=GetLastError();returnFALSE;}char*pRecvBuf=pRecvData;intiSize=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);}DWORDBIOServerSample(){BIO*sbio,*bbio,*acpt,*out;intlen;chartmpbuf[1024];SSL_CTX*ctx;SSL*ssl;ERR_load_crypto_strings();ERR_load_SSL_strings();OpenSSL_add_all_algorithms();//Might seed PRNG herectx=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);return0;}//Might do other things here like setting verify locations and//DH and/or RSA temporary key callbacks// New SSL BIO setup as serversbio=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 retriesSSL_set_mode(ssl,SSL_MODE_AUTO_RETRY);// Create the buffering BIObbio=BIO_new(BIO_f_buffer());//Add to chainsbio=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 BIOif(BIO_do_accept(acpt)<=0){fprintf(stderr,"Error setting up accept BIO\n");ERR_print_errors_fp(stderr);return0;}// Now wait for incoming connectionif(BIO_do_accept(acpt)<=0){fprintf(stderr,"Error in connection\n");ERR_print_errors_fp(stderr);return0;}// 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);return0;}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 headersif((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 itBIO_flush(sbio);BIO_free_all(sbio);returnTRUE;}int__stdcallWinMain(__in HINSTANCE hInstance,__in_opt HINSTANCE hPrevInstance,__in LPSTR lpCmdLine,__inintnShowCmd){WSAData wsa;intret=WSAStartup(0x0202,&wsa);if(ret){returnFALSE;}SSL_library_init();SSL_load_error_strings();OpenSSL_add_all_algorithms();charszdata[0x4000];for(inti=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;charszrecv[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;// }returnTRUE;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 16:02:18

如何快速上手switch_user?5分钟实现用户无缝切换

如何快速上手switch_user&#xff1f;5分钟实现用户无缝切换 【免费下载链接】switch_user Easily switch current user 项目地址: https://gitcode.com/gh_mirrors/sw/switch_user 想要在Rails开发中轻松切换不同用户账户进行测试吗&#xff1f;switch_user是一个功能强…

作者头像 李华
网站建设 2026/7/15 16:02:07

switch_user:革命性用户切换工具,让开发与调试效率提升10倍

switch_user&#xff1a;革命性用户切换工具&#xff0c;让开发与调试效率提升10倍 【免费下载链接】switch_user Easily switch current user 项目地址: https://gitcode.com/gh_mirrors/sw/switch_user switch_user是一款专为开发者打造的革命性用户切换工具&#xff…

作者头像 李华
网站建设 2026/7/15 16:01:58

小程序毕业设计-基于 SpringBoot + 小程序的在线答题系统 基于 SpringBoot 的在线考试测评系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/15 16:01:54

Python通达信数据获取终极方案:5分钟搭建你的股票分析系统

Python通达信数据获取终极方案&#xff1a;5分钟搭建你的股票分析系统 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 还在为获取A股市场数据而烦恼吗&#xff1f;面对复杂的API接口、不稳定的数据…

作者头像 李华
网站建设 2026/7/15 16:01:24

ChatGPT写周报月报终极指南:不是“怎么写”,而是“让领导觉得你早该升职”——融合行为心理学+组织政治学的高阶表达框架

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ChatGPT写周报月报的底层认知跃迁 过去&#xff0c;周报月报被视为流程性负担——模板固化、信息堆砌、价值稀薄。而今&#xff0c;当ChatGPT介入这一场景&#xff0c;真正的变革并非来自“自动填充”&…

作者头像 李华