一、实验内容
-
安装openSSL
-
编写一个服务器的程序,服务器端的功能是建立SSL网络服务,接受客户端的SSL连接,收发SSL消息
-
编写一个客户端的程序,客户端的功能是通过SSL协议连接服务器,收发SSL消息
-
生成SSL证书
-
撰写试验报告,包括了服务器端和客户端运行结果截图,以及生成的SSL证书
二、实验框架
程序分为两部分,客户端和服务器端,我们的目的是利用SSL/TLS的特性保证通信双方能够互相验证对方身份(真实性),并保证数据的完整性, 私密性。
服务器认证阶段
-
客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接
-
服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息
-
客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器
-
服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器
用户认证阶段
在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。
流程图如下:
客户端以及服务器端的框架如下:
三、实验步骤
3.1 安装openSSL
下载openSSL的exe文件,在 https://slproweb.com/products/Win32OpenSSL.html 网站上下载合适的安装包。
下载完后打开安装,选择安装位置,64位和32位不要安装在同一个目录下。
选择把dll复制到OpenSSL目录下。
安装完成后,如果有捐款意向的可以捐款,没有意向则取消掉钩,然后点“Finish” 。
3.2 VS2017搭建openssl环境
新建空项目,然后配置项目属性(包含目录添加进openssl的include文件夹;库目录添加openssl的lib文件夹)。
将OpenSSL安装目录下bin文件夹中的“libeay32.dll”和“ssleay32.dll”(名字后面的版本号可能因更新而不同)复制到工程目录下。
3.3 生成证书
首先要生成服务器端的私钥(key文件)
openssl genrsa -des3 -out server.key 1024
运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密算法,当然也可以选用其他你认为安全的算法),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令。如果觉得不方便,也可以去除这个口令,但一定要采取其他的保护措施!
去除key文件口令的命令:
openssl rsa -in server.key -out server.key
openssl req -new -key server.key -out server.csr
生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书。屏幕上将有提示,依照其指示一步一步输入要 求的个人信息即可。
对客户端也作同样的命令生成key及csr文件。
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr
首先生成CA的key文件,再生成CA自签名的证书。
首先生成CA的key文件:
openssl genrsa-des3 -out ca.key 1024
再生成CA自签名的证书:
openssl req -new -x509 -key ca.key -out ca.crt
用生成的CA的证书为刚才生成的server.csr,client.csr文件签名。
openssl中还附带了一个叫CA.pl的文件,可用其生成文件。
3.4 服务器和客户端程序编写
3.4.1 客户端编写框架
/*生成一个SSL结构*/
meth = SSLv23_client_method();
ctx = SSL_CTX_new (meth);
ssl = SSL_new(ctx);
/*下面是正常的socket过程*/
fd = socket();
connect();
/*把建立好的socket和SSL结构联系起来*/
SSL_set_fd(ssl,fd);
/*SSL的握手过程*/
SSL_connect(ssl);
/*接下来用SSL_write(), SSL_read()代替原有的write(),read()即可*/
SSL_write(ssl,"我是客户端",strlen("我是客户端"));
3.4.2 服务器编写框架
/*生成一个SSL结构*/
meth = SSLv23_server_method();
ctx = SSL_CTX_new (meth);
ssl = SSL_new(ctx);
/*下面是正常的socket过程*/
fd = socket();
bind();
listen();
accept();
/*把建立好的socket和SSL结构联系起来*/
SSL_set_fd(ssl,fd);
/*SSL的握手过程*/
SSL_connect(ssl);
/*接下来用SSL_write(), SSL_read()代替原有的write(),read()即可*/
SSL_read (ssl, buf, sizeof(buf));
四、实验结果截图
服务器(server)运行截图和客户端(client1)运行截图,证书信息也在截图中。
经过三次握手,数据交互,服务器收到了客户端传来的“我是客户端消息”,客户端收到了服务器传来的“服务器收到了”数据。