网络安全程序设计报告.docx
《网络安全程序设计报告.docx》由会员分享,可在线阅读,更多相关《网络安全程序设计报告.docx(23页珍藏版)》请在冰豆网上搜索。
![网络安全程序设计报告.docx](https://file1.bdocx.com/fileroot1/2022-12/7/50a6b57c-4834-4261-9230-28d0e58d2b7d/50a6b57c-4834-4261-9230-28d0e58d2b7d1.gif)
网络安全程序设计报告
目录
一、实验选题3
二、实验环境3
三、系统设计3
1、Windows下进行OpenSSL编程的主要步骤3
2、系统框图4
3、重要函数4
四、实验过程截图16
1、安装openssl17
2、客户端与服务器端安全通信18
五、实验与课程总结20
六、源代码清单20
一、实验选题
基于OpenSSL的安全聊天系统
–Windows或Linux平台均可
–点到点模式
–基于OpenSSL的安全套接字通信
–客户端服务器双向认证
–聊天记录本地加密存储,输入正确口令可查看
二、实验环境
操作系统WindowsXPsp3
开发平台VC++6.0
其它OpenSSLActivePerl
三、系统设计
1、Windows下进行OpenSSL编程的主要步骤
1.安装ActivePerl,阅读openssl开发包中的install.w32,编译openssl,;
2.下载CA证书并对其进行公私钥的分割,使用openssl生成证书文件;
3.阅读相关文档,熟悉OpenSSL编程接口,编写server和client端代码;
4.将所需要的文件放到源代码目录,调试并运行程序,使用证书来验证进行安全通信的过程及身份认证方式。
2、系统框图
3、重要函数
Client:
连接服务器端并接收服务器消息的线程函数:
voidClientThreadProc(void*void_parm)
{
WSADATAwsaData;
interr;
intsd;
structsockaddr_insa;
SSL*ssl;
X509*server_cert;
char*str;
charbuffer[8912];
intmaxFd;
fd_setwriteFds,readFds,excFds;
DWORDdwIP;
dwIP=(DWORD)void_parm;
//char*msg=(char*)malloc(128);
charmsg[128];
//初始化windowssocket
if(WSAStartup(MAKEWORD(2,2),&wsaData))
{
return;
}
//新建socket
sd=socket(AF_INET,SOCK_STREAM,0);
memset(&sa,'\0',sizeof(sa));
//设置服务端IP地址、和端口
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=dwIP;
sa.sin_port=htons(8443);
//连接服务器
err=connect(sd,(structsockaddr*)&sa,sizeof(sa));
if(err<0)
{
//char*msg=(char*)malloc(128);
strcpy(msg,"连接服务器失败!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
return;
}
strcpy(msg,"SSL开始握手!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
//新建SSL句柄
ssl=SSL_new(ctx);
//设置socket句柄到SSL句柄
SSL_set_fd(ssl,sd);
//SSL连接
err=SSL_connect(ssl);
if(err!
=1)
{
//char*msg=(char*)malloc(128);
strcpy(msg,"SSL连接服务器失败!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
return;
}
server_cert=SSL_get_peer_certificate(ssl);
strcpy(msg,"Clientcertificate:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
str=X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
strcpy(msg,"subject:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
strcpy(msg,str);
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
OPENSSL_free(str);
str=X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
strcpy(msg,"issuer:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
strcpy(msg,str);
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
OPENSSL_free(str);
X509_free(server_cert);
//printf("SSLconnectionusing%s\n",SSL_get_cipher(ssl));
strcpy(msg,"SSLconnectionusing:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
/*打印所有加密算法的信息(可选)*/
strcpy(msg,SSL_get_cipher(ssl));
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
maxFd=sd;
client.fd=sd;
client.ssl=ssl;
strcpy(msg,"连接服务器成功!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
for(;;)
{
FD_ZERO(&writeFds);
FD_ZERO(&readFds);
FD_ZERO(&excFds);
FD_SET(sd,&readFds);
//select异步等待服务器
intnfd=select(maxFd+1,&readFds,&writeFds,&excFds,NULL);
if(nfd<=0)
{
if(errno==EINTR)/*interruptedsystemcall*/
continue;
return;
}
if(FD_ISSET(sd,&readFds))
{
//接收服务器消息
intlen=SSL_read(ssl,buffer,sizeof(buffer));
if(len<=0)
{
char*msg=(char*)malloc(128);
strcpy(msg,"服务器退出!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,sd,(long)msg);
return;
}
buffer[len]='\0';
char*msg=(char*)malloc(len+1);
strcpy(msg,buffer);
//通过WM_CLIENT_MSG消息,发送到主窗体
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLIENT_MSG,sd,(long)msg);
}
}
return;
}
链接服务器:
voidCClientDlg:
:
OnConnect()
{
unsignedlongidThread;
DWORDdwIP=0;
CIPipaddr;//让用户输入客户端IP
m_liststate.ResetContent();
if(client.fd==0)//判断是否已经连接
{
if(ipaddr.DoModal()==IDOK)
{
dwIP=inet_addr(ipaddr.IP.GetBuffer(0));
}
//创建线程,连接服务器,并接收服务器端消息
CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)ClientThreadProc,
(void*)dwIP,0,&idThread);
}
else
{
m_liststate.InsertString(0,"已经连接!
");
}
}
发送消息到服务器:
voidCClientDlg:
:
OnSend()
{
UpdateData();
if(client.fd!
=0)
{
//发送消息
SSL_write(client.ssl,m_str.GetBuffer(0),m_str.GetLength());
m_str.ReleaseBuffer();
}
else
{
return;
}
//插入发送的消息的列表框
m_list.InsertString(0,m_str);
m_str.Empty();
UpdateData(FALSE);
((CEdit*)GetDlgItem(IDC_EDIT1))->SetActiveWindow();
}
处理WM_CLIENT_MSG消息:
LRESULTCClientDlg:
:
OnClientMsg(WPARAMwParam,LPARAMlParam)
{
CStringmsg;
msg.Format("[Socket:
%d]%s",wParam,(char*)lParam);
m_list.InsertString(0,msg);
free((void*)lParam);
return0L;
}
LRESULTCClientDlg:
:
OnStateMsg(WPARAMwParam,LPARAMlParam)
{
CStringmsg;
msg.Format("[Socket:
%d]%s",wParam,(char*)lParam);
m_liststate.InsertString(-1,msg);
//m_liststate.AddString(msg);
//free((void*)lParam);
return0L;
}
voidCClientDlg:
:
OnDestroy()
{
WSACleanup();
SSL_CTX_free(ctx);
CDialog:
:
OnDestroy();
}
断开链接:
voidCClientDlg:
:
OnDisconnect()
{
if(client.fd!
=0)
{
closesocket(client.fd);
SSL_shutdown(client.ssl);
SSL_free(client.ssl);
client.ssl=NULL;
client.fd=0;
m_liststate.InsertString(0,"已断开和服务器的链接!
");
m_liststate.ResetContent();
}
}
Server:
处理客户端事务线程函数,接收客户端消息:
voidclient(void*void_parmint)
{
intclientFd=(int)void_parmint;
intmaxFd;
intlen;
intflag=0;
fd_setwriteFds,readFds,excFds;
charbuffer[8192];
descriptor_tclientDesc;
clientDesc.fd=clientFd;
clientDesc.ssl=NULL;
SSL*ssl;
char*str;
X509*client_cert;
//新建SSL连接句柄
if((ssl=SSL_new(ctx))==NULL)
{
return;
}
//设置SSL连接Socket句柄
SSL_set_fd(ssl,clientFd);
//接收SSL连接
if(SSL_accept(ssl)<=0)
{
return;
}
//char*msg=(char*)malloc(128);
charmsg[128];
strcpy(msg,"SSLconnectionusing");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
/*打印所有加密算法的信息(可选)*/
strcpy(msg,SSL_get_cipher(ssl));
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
/*得到客户端的证书并打印些信息(可选)*/
client_cert=SSL_get_peer_certificate(ssl);
if(client_cert!
=NULL){
//printf("Clientcertificate:
\n");
strcpy(msg,"Clientcertificate:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
str=X509_NAME_oneline(X509_get_subject_name(client_cert),0,0);
//printf("\tsubject:
%s\n",str);
strcpy(msg,"subject:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)str);
OPENSSL_free(str);
str=X509_NAME_oneline(X509_get_issuer_name(client_cert),0,0);
//printf("\tissuer:
%s\n",str);
strcpy(msg,"issuer:
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)str);
OPENSSL_free(str);
X509_free(client_cert);/*如不再需要,需将证书释放*/
}
clientDesc.ssl=ssl;
//把客户端链接句柄保存到全局变量中。
for(inti=0;i{
if(Clients[i].fd==0)
{
Clients[i].fd=clientFd;
Clients[i].ssl=ssl;
flag=1;
break;
}
}
if(!
flag)
{
//已经达到链接最大限制
SSL_write(ssl,"服务器已满!
",strlen("服务器已满!
"));
SSL_shutdown(ssl);
SSL_free(ssl);
return;
}
maxFd=clientFd;
for(;;)
{
FD_ZERO(&writeFds);
FD_ZERO(&readFds);
FD_ZERO(&excFds);
FD_SET(clientFd,&readFds);
//异步的方式等待客户端数据
intnfd=select(maxFd+1,&readFds,&writeFds,&excFds,NULL);
if(nfd<=0)
{
if(errno==EINTR)/*interruptedsystemcall*/
continue;
return;
}
if(FD_ISSET(clientFd,&readFds))//有客户端数据需要读取
{
//接收客户端数据
len=SSL_read(clientDesc.ssl,buffer,sizeof(buffer));
if(len<=0)
{
//char*msg=(char*)malloc(128);
strcpy(msg,"客户端退出!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,clientFd,(long)msg);
return;
}
buffer[len]='\0';
char*msg1=(char*)malloc(len+1);
strcpy(msg1,buffer);
//发送WM_CLIENT_MSG消息到主窗体,把接收到的消息显示到列表框
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLIENT_MSG,clientFd,(long)msg1);
}
}
return;
}
接收连接线程函数:
voidAcceptThreadProc(void*void_parm)
{
intsockFd=(int)void_parm;
HANDLEhd;
unsignedlongidThread;
intclientFd;
//接收连接
clientFd=accept(sockFd,NULL,NULL);
if(clientFd<0){
if(errno==EINTR)/*interruptedsystemcall*/
return;
ExitThread(0);
}
//接收客户端连接后,开启线程处理客户端事务即接收客户端消息
hd=CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)client,
(void*)clientFd,0,&idThread);
}
启动服务线程函数:
voidStartServer(void*void_parm)
{
WSADATAwsaData;
interr;
intlisten_sd;
unsignedlongidThread;
structsockaddr_insa_serv;
HANDLEhd;
intport=(int)void_parm;
//初始化windowssocket
if(WSAStartup(MAKEWORD(2,2),&wsaData))
{
char*msg=(char*)malloc(128);
strcpy(msg,"初始化Socket失败!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,0,(long)msg);
return;
}
//新建socket句柄
listen_sd=socket(AF_INET,SOCK_STREAM,0);
//初始化sockaddr_in结构体,设置TCP协议和端口
memset(&sa_serv,'\0',sizeof(sa_serv));
sa_serv.sin_family=AF_INET;
sa_serv.sin_addr.s_addr=INADDR_ANY;
sa_serv.sin_port=htons(port);
//绑定端口
err=bind(listen_sd,(structsockaddr*)&sa_serv,
sizeof(sa_serv));
if(err<0)
{
char*msg=(char*)malloc(128);
strcpy(msg,"绑定Socket失败!
");
SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_STATE_MSG,listen_sd,(long)msg);
return;
}
//侦听,tcp连接
err=listen(listen_sd,5);
char*msg=(char*)malloc(128);
strcpy(msg,"启动服务成功!
");