#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#include "openssl/ssl.h"
#include "openssl/rand.h"
int InitWinsock()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested,&wsaData);
if (err != 0)
{
return 0;
}
if (LOBYTE(wsaData.wVersion) != 1||
HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return 0;
}
}
SOCKET CreateSocket()
{
SOCKET hsock = INVALID_SOCKET;
hsock = socket(AF_INET,SOCK_STREAM,0);
if (hsock == INVALID_SOCKET)
{
int last_error = WSAGetLastError();
printf("创建套接字失败,错误代码是:%s\n",last_error);
}
return hsock;
}
int ConnectServer(SOCKET hSocket)
{
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
//连接到服务器
int nRet = connect(hSocket,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
if (nRet == SOCKET_ERROR)
{
int last_err = WSAGetLastError();
printf("连接失败,错误代码是:%s\n",last_err);
return 0;
}
return 1;
}
int InitOpenSSL()
{
if (!SSL_library_init())
return 0;
SSL_load_error_strings();
return 1;
}
//回调函数中要实现的功能就是把密码到buf这个字符缓冲区中(可使用strcpy等类似函数),
//并注意,密码的长度不要超过size。
int PasswordCB(char *buf,int size,int flag,void* userdata)
{
printf("input pass!\n");
scanf("%s",buf);
const char* pass = "1993426";
if (size < strlen(pass)+1 || strcmp(buf,pass))
{
printf("wrong!\n");
return 0;
}
strcpy(buf,pass);
return strlen(buf);
}
int VerifyCB(int ok,X509_STORE_CTX *store)
{
if (!ok)
{
int err = X509_STORE_CTX_get_error(store);
printf("%s:%s\n",err,X509_verify_cert_error_string(err));
}
return ok;
}
SSL_CTX* InitSSLContext()
{
const SSL_METHOD *meth = NULL;
SSL_CTX* ctx = NULL;
meth = SSLv23_method();
ctx = SSL_CTX_new(meth);
//加载客户端程序证书链
if (!SSL_CTX_use_certificate_chain_file(ctx,"ClientAppChain.pem"))
{
printf("加载客户端程序证书链失败!\n");
return NULL;
}
//回调函数中要实现的功能就是把密码到buf这个字符缓冲区中(可使用strcpy等类似函数),
//并注意,密码的长度不要超过size。
SSL_CTX_set_default_passwd_cb(ctx,PasswordCB);
//加载客户端程序私钥文件
if (!SSL_CTX_use_PrivateKey_file(ctx,"ClientApp_PrivateKey.pem",
SSL_FILETYPE_PEM))
{
printf("加载客户端程序私钥文件失败!\n");
return NULL;
}
//加载客户端程序所信任的CA
if (!SSL_CTX_load_verify_locations(ctx,"MyTestCA_Certificate.pem",
NULL))
{
printf("加载客户端程序所信任的CA失败!\n");
return NULL;
}
//加载OpenSSL默认信任的CA
if (!SSL_CTX_set_default_verify_paths(ctx))
{
printf("加载OpenSSL默认信任的CA失败!\n");
return NULL;
}
//验证深度为1
SSL_CTX_set_verify_depth(ctx,1);
//前者要求服务器提供证书,后者用于输出Openssl
//握手过程中验证服务器证书链失败时的错误信息
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,VerifyCB);
SSL_CTX_set_mode(ctx,SSL_MODE_AUTO_RETRY);
return ctx;
}
//简单的校验,仅检查Common Name
int CheckCertificate(SSL* ssl)
{
X509* cert = SSL_get_peer_certificate(ssl);
if (cert == NULL)
return 0;
X509_NAME* subjectName = X509_get_subject_name(cert);
if (subjectName == NULL)
{
printf("证书无效!\n");
return 0;
}
char buf[256];
char * str;
if (X509_NAME_get_text_by_NID(subjectName,
NID_commonName,buf,256)>0)
{
if (strcmp(buf,"ServerAPP") == 0)
/*得到服务器端的证书并打印信息*/
str = X509_NAME_oneline(subjectName,0,0);
printf("服务器端证书:%s\n",str);
str = X509_NAME_oneline(X509_get_issuer_name(cert),0,0);
printf("证书签署者:%s\n",str);
return 1;
}
printf("证书无效!\n");
return 0;
}
int* CreateRand()
{
int seed[100];
srand((unsigned)time(NULL));
for(int i=0;i<100;i++)
seed[i] = rand();
//RAND_seed(seed,sizeof(seed));
return seed;
}
void Test(SSL* ssl)
{
char buf[256];
while (1)
{ //从文件结构体指针stream中读取数据,每次读取一行。
//读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),
//如果文件中的该行,不足bufsize个字符,则读完该行就结束。
if (!fgets(buf,sizeof(buf)/sizeof(buf[0]),stdin))
{
SSL_shutdown(ssl);
break;
}
int len = strlen(buf);
int nSend = 0;
while (nSend < len)
{ //将buf+nSend中,len-nSend数目的字节写入ssl
//返回值nRet为成功写入的字节数
int nRet = SSL_write(ssl,buf+nSend,len-nSend);
if (nRet <= 0)
{
printf("SSL_write发生错误!\n");
SSL_clear(ssl);
break;
}
nSend += nRet;
}
}
}
void main()
{
if (!InitWinsock())
return;
printf("InitWinsock!\n");
//SOCKET sockClient = INVALID_SOCKET;
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
BIO *sbio = NULL;
int nRet = 0;
if (!InitOpenSSL())
return;
ctx = InitSSLContext();
if (ctx == NULL)
return;
ssl = SSL_new(ctx);
SOCKET sockClient = CreateSocket();
if (INVALID_SOCKET == sockClient)
return;
if (!ConnectServer(sockClient))
return;
sbio = BIO_new_socket(sockClient,BIO_NOCLOSE);
SSL_set_bio(ssl,sbio,sbio);
//增加随机数的不确定性
RAND_seed(CreateRand(),sizeof(CreateRand()));
/*TCP已建立!开始握手过程*/
printf("SSL开始握手过程!\n");
if (SSL_connect(ssl) <= 0)
{
printf("SSL握手错误!\n");
return ;
}
/*打印所有加密算法的信息*/
printf("SSL连接所用加密算法有:%s\n",SSL_get_cipher(ssl));
//printf("c");
if (!CheckCertificate(ssl))
return ;
//printf("g");
Test(ssl);
//SSL_write(ssl,"Hello world",strlen("Hello World!"));
if (ssl) SSL_free(ssl);
if (ctx) SSL_CTX_free(ctx);
if (sockClient != INVALID_SOCKET)
closesocket(sockClient);
WSACleanup();
/*char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"hello,I am Client",strlen("hello,I am Client")+1,0);
closesocket(sockClient);
WSACleanup();*/
}
没有合适的资源?快使用搜索试试~ 我知道了~
client&server.zip_client/server_openssl tcp server_tcp_服务端开发
共96个文件
tlog:40个
pem:6个
pdb:5个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 159 浏览量
2022-07-14
09:44:04
上传
评论
收藏 60.23MB ZIP 举报
温馨提示
服务器端和客户端,基于tcp的传输协议,使用openssl库进行开发,其中已经生成了证书和密钥文件(下载openssl库可生成)
资源推荐
资源详情
资源评论
收起资源包目录
client&server.zip (96个子文件)
TcpClient
TcpClient
MyTestCA_Certificate.pem 1KB
TcpClient.vcxproj.user 143B
TcpClient.vcxproj 4KB
TcpClient.sln 884B
TcpClient.suo 11KB
ClientAppChain.pem 2KB
TcpClient.vcxproj.filters 947B
ClientApp_PrivateKey.pem 963B
TcpClient.cpp 6KB
ipch
tcpclient-4eb4d15b
tcpclient-d8299d2.ipch 43.81MB
TcpClient.sdf 32.83MB
Debug
vc100.idb 651KB
link.1384-cvtres.read.1.tlog 2B
link.1384-cvtres.write.1.tlog 2B
link.1384.write.1.tlog 2B
CL.write.1.tlog 278B
TcpClient.ilk 445KB
TcpClient.pdb 763KB
CL.read.1.tlog 25KB
link.1384.read.1.tlog 2B
TcpClient.exe.embed.manifest.res 472B
mt.read.1.tlog 482B
rc.write.1.tlog 254B
TcpClient.lastbuildstate 55B
rc.read.1.tlog 350B
mt.command.1.tlog 370B
cl.command.1.tlog 590B
link-cvtres.read.1.tlog 2B
TcpClient.exe.embed.manifest 406B
link.write.1.tlog 672B
link-cvtres.write.1.tlog 2B
link.command.1.tlog 2KB
rc.command.1.tlog 496B
link.read.1.tlog 3KB
TcpClient.log 3KB
mt.write.1.tlog 274B
TcpClient.exe 34KB
TcpClient.obj 73KB
TcpClient.exe.intermediate.manifest 381B
vc100.pdb 324KB
TcpClient_manifest.rc 208B
TcpClient.vcxproj.user 143B
TcpClient.vcxproj 4KB
TcpClient.sln 884B
TcpClient.suo 13KB
TcpClient.vcxproj.filters 1KB
ipch
tcpclient-4eb4d15b
tcpclient-d8299d2.ipch 43.81MB
TcpClient.sdf 35.89MB
Debug
TcpClient.ilk 553KB
TcpClient.pdb 771KB
TcpClient.exe 32KB
TcpServer
TcpServer.sdf 35.89MB
TcpServer.sln 894B
TcpServer.suo 17KB
ipch
tcpserver-cebc12a3
tcpserver-74907aea.ipch 43.81MB
Debug
TcpServer.exe 33KB
TcpServer.ilk 596KB
TcpServer.pdb 763KB
TcpServer
MyTestCA_Certificate.pem 1KB
ServerApp_PrivateKey.pem 951B
TcpServer.vcxproj 4KB
TcpServer.vcxproj.filters 947B
serverAppChain.pem 2KB
TcpServer.vcxproj.user 143B
TcpServer.cpp 6KB
Debug
vc100.idb 635KB
link.10376-cvtres.read.1.tlog 2B
CL.write.1.tlog 278B
CL.read.1.tlog 25KB
mt.read.1.tlog 482B
rc.write.1.tlog 254B
TcpServer.obj 70KB
rc.read.1.tlog 350B
TcpServer.lastbuildstate 45B
link.2260-cvtres.read.1.tlog 2B
mt.command.1.tlog 370B
link.10376.write.1.tlog 2B
cl.command.1.tlog 590B
link-cvtres.read.1.tlog 2B
link.2260.write.1.tlog 2B
link.2260.read.1.tlog 2B
TcpServer.exe.embed.manifest 406B
TcpServer_manifest.rc 208B
link.2260-cvtres.write.1.tlog 2B
link.write.1.tlog 612B
TcpServer.log 3KB
link.10376-cvtres.write.1.tlog 2B
link-cvtres.write.1.tlog 2B
link.10376.read.1.tlog 2B
link.command.1.tlog 2KB
rc.command.1.tlog 496B
link.read.1.tlog 3KB
TcpServer.exe.intermediate.manifest 381B
mt.write.1.tlog 274B
TcpServer.exe.embed.manifest.res 472B
vc100.pdb 324KB
共 96 条
- 1
资源评论
weixin_42653672
- 粉丝: 93
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Screenshot_20240430_144340_com.ss.android.ugc.live.jpg
- 回到山沟沟.mp3
- 基于matlab实现自适应波束形成RLS及LMS算法仿真源程序1.rar
- 基于matlab实现自己编写的基于卡尔曼滤波的利用加速度传感器的计步器,测试数据是传感器放在腰部和手臂 .rar
- 基于matlab实现阵列信号处理,波束形成.rar
- 111111111111111111
- 基于matlab实现计步器编程;对当前的计步器装置的数值算法模拟 .rar
- Mdb学习查看PW;access;mdb;pw;password;patch
- 基于matlab实现关于语音信号声源定位DOA估计所用的一些传统算法.rar
- 基于ultralytics-yolov8, 将其检测/分类/分割/姿态等任务移植到rk3588上
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功