2017-2018-1 20155314《信息安全系统设计基础》实验五 通讯协议设计
2017-2018-1 20155314《信息安全系统设计基础》实验五 通讯协议设计
通讯协议设计-1
实验要求
在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的作业
提交运行结果截图
学到的知识
Linux下的应用大多可以直接使用,也可以获取源代码自己进行编译、安装,使用源代码安装的过程一般是:
- configure
- make
- make install
gcc -o test_openssl test_openssl.c -I /usr/local/ssl/include -L /usr/local/ssl/lib -lcrypto -ldl -lpthread
上面这句表示在编译test_openssl.c时:
- -o test_openssl test_openssl.c:
将test_openssl.c编译生成可执行文件test_openssl(如果不给出这个选项,gcc就给出预设的可执行文件a.out)
- -I /usr/local/ssl/include:
将/usr/local/ssl/include目录作为第一个寻找头文件的目录,寻找的顺序是:/usr/local/ssl/include-->/usr/include-->/usr/local/include
- -L /usr/local/ssl/lib:
将/usr/local/ssl/lib目录作为第一个寻找库文件的目录,寻找的顺序是:/usr/local/ssl/lib-->/lib-->/usr/lib-->/usr/local/lib
- -L:指定链接库的文件夹地址
- -ldl:加载动态库
- -lcrypto:导入OpenSSL所需包
- -lpthread:链接POSIX thread库
实验步骤
一、Linux下OpenSSL的安装
-
访问OpenSSL的官网 http://www.openssl.org/source/ ,下载最新版本的OpenSSL:
这里为了跟老师的教程同步,我选择下载教程给出的OpenSSL版本:OpenSSL 1.1.0alpha -
在Ubuntu ARM V12B V2.0虚拟机中使用
tar xzvf openssl-1.1.0-pre1.tar.gz命令解压源代码; -
使用
cd openssl-1.1.0-pre1命令进入源代码目录; -
使用下列命令编译安装:
$ ./config $ make $ sudo make install -
使用
make test命令测试安装是否正确:
测试全部通过,表明安装无误~
二、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 test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread命令编译生成可执行文件test_openssl -
执行
echo $?,结果打印0,表明测试通过,如下图:
通讯协议设计-2
实验要求
在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
提交测试截图
学到的知识
-
混合密码系统介绍

-
OpenSSL流程
- 初始化
- 选择会话协议和创建会话环境
- 建立SSL套接字
- 完成SSL握手
- 从SSL套接字中提取对方的证书信息
- 数据传输
- 结束SSL通信
-
OpenSSL应用编程框架
-
Server端:
ctx = SSL_CTX_new (SSLv23_server_method()); ssl = SSL_new (ctx); fd = socket (); bind (); listen (); accept (); SSL_set_fd (ssl, fd); SSL_accept (ssl); SSL_read (); -
Client端:
ctx = SSL_CTX_new (SSLv23_client_method()); ssl = SSL_new (ctx); fd = socket (); connect (); SSL_set_fd (ssl, fd); SSL_connect (ssl); SSL_write ();
-
实验代码
-
server.c:
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 1024
int 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; -
client.c:
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 1024
int 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;
}
运行截图

通讯协议设计-3
实验要求
运行实验箱中,ARM调用Z32算法的实验,提交实验截图
用Z32的国密算法重新改写“wc服务器”的混合密码系统防护,提交运行截图
运行结果
- 未要求完成
实验中遇到的问题及解决过程
OpenSSL编译安装问题
-
问题描述:
OpenSSL安装过程中
make install时报错:

-
主要原因:
被老师博客教程中写的
./configure所困惑:
我在OpenSSL安装目录中并没有找到可执行文件configure,但却发现了两个与之非常相似的可执行文件config和Configure,于是便不假思索地输入命令./Configure,导致到make install这一步时出错,错误原因未知... -
解决方法:
正解自然是用
./config命令执行可执行文件config,再make和make install,该问题便迎刃而解了:



浙公网安备 33010602011771号