2018-2019-1 20165236 实验五 通讯协议设计
实验内容
任务一:在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的作业
一、Linux下OpenSSL的安装与测试
openSSL简介:
1、openSSL是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用;
2、OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库、应用程序;
3、SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。SSL能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上;
4、OpenSSL的应用程序主要包括密钥生成、证书管理、格式转换、数据加密和签名、SSL测试以及其它辅助配置功能。
下载openSSL:
在官网下载程序 :https://www.openssl.org/;
Linux下的应用大多可以直接使用,也可以获取源代码自己进行编译、安装,使用源代码安装的过程一般是:
configure
make
make install
OpenSSL的安装也是这样。首先解压源代码:
tar xzvf openssl-1.1.0-pre1.tar.gz
然后进入源代码目录:cd openssl-1.1.0-pre1
然后使用下列命令编译安装:
./configure
make
sudo make install
如图所示:
Linux下OpenSSL的使用
OpenSSL应用程序
通过man openssl查看帮助文档:
OpenSSL密码算法库
编写一个测试代码test_openssl.c:
#include <stdio.h>
#include <openssl/evp.h>
int main() {
OpenSSL_add_all_algorithms();
return 0;
}
然后用下面命令编译:
gcc -o to test_openssl.c -I /usr/local/ssl/inlcude -L /usr/local/ssl/lib -ldl -lpthread
执行./to;echo $?结果打印0.
任务二:在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
服务器server.c中使用openssl的步骤为:
1.SSL库初始化:SSL_library_init();
2.载入所有SSL算法和SSL错误消息;
3.入用户的数字证书,此证书用来发送给客户端;
4.载入用户私钥并检查用户私钥是否正确;
5.开启一个socket监听;
6.基于ctx产生一个新的ssl,将连接用户的socket加入到ssl,建立ssl连接;
7.处理每个连接上的数据收发;
8.关闭并释放ssl,关闭socket,释放CTX。
产品代码
服务器代码:
#include <stdio.h>
#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <unistd.h>#include <arpa/inet.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/evp.h> #define MAXBUF 1024int main(int argc, char **argv)
{ int sockfd, new_fd;socklen_t len;struct sockaddr_in my_addr, their_addr;unsigned int myport, lisnum;char buf[MAXBUF + 1];SSL_CTX *ctx;if (argv[1])
myport = atoi(argv[1]);else myport = 7838;if (argv[2])
lisnum = atoi(argv[2]);else lisnum = 2;/* SSL 库初始化 */
SSL_library_init();/* 载入所有 SSL 算法 */OpenSSL_add_all_algorithms();/* 载入所有 SSL 错误消息 */SSL_load_error_strings();/* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */ctx = SSL_CTX_new(SSLv23_server_method());/* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */if (ctx == NULL) { ERR_print_errors_fp(stdout); exit(1);}/* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); exit(1);}/* 载入用户私钥 */if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0){ ERR_print_errors_fp(stdout); exit(1);}/* 检查用户私钥是否正确 */if (!SSL_CTX_check_private_key(ctx)) { ERR_print_errors_fp(stdout); exit(1);}/* 开启一个 socket 监听 */
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1);} else printf("socket created\n");bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = PF_INET;my_addr.sin_port = htons(myport);my_addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
== -1) { perror("bind"); exit(1);} else printf("binded\n");if (listen(sockfd, lisnum) == -1) {
perror("listen"); exit(1);} else printf("begin listen\n");while (1) {
SSL *ssl; len = sizeof(struct sockaddr); /* 等待客户端连上来 */ if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len)) == -1) { perror("accept"); exit(errno); } else printf("server: got connection from %s, port %d, socket %d\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);/* 基于 ctx 产生一个新的 SSL */
ssl = SSL_new(ctx); /* 将连接用户的 socket 加入到 SSL */ SSL_set_fd(ssl, new_fd); /* 建立 SSL 连接 */ if (SSL_accept(ssl) == -1) { perror("accept"); close(new_fd); break; }/* 开始处理每个新连接上的数据收发 */
bzero(buf, MAXBUF + 1); strcpy(buf, "server->client"); /* 发消息给客户端 */ len = SSL_write(ssl, buf, strlen(buf));if (len <= 0) {
printf ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buf, errno, strerror(errno)); goto finish; } else printf("消息'%s'发送成功,共发送了%d个字节!\n", buf, len);bzero(buf, MAXBUF + 1);
/* 接收客户端的消息 */ len = SSL_read(ssl, buf, MAXBUF); if (len > 0) printf("接收消息成功:'%s',共%d个字节的数据\n", buf, len); else printf ("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno)); /* 处理每个新连接上的数据收发结束 */ finish: /* 关闭 SSL 连接 */ SSL_shutdown(ssl); /* 释放 SSL */ SSL_free(ssl); /* 关闭 socket */ close(new_fd);}/* 关闭监听的 socket */close(sockfd);/* 释放 CTX */SSL_CTX_free(ctx);return 0;}结果截图:
二、实验过程中遇到的问题:
openssl-1.0.1k>nmake -f ms\ntdll.mak提示:
'ml' 既不是内部或外部命令也不是可运行的程序或批处理文件;解决方法:
下载masm并把其中的ml.exe拷贝至C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin下即可。