2017-2018-1 20155232 实验五 通讯协议设计
Linux下OpenSSL的安装与使用
OpenSSL简介
OpenSSL是一个SSL协议的开源实现,采用C语言作为开发语言,具备了跨平台的能力,支持Unix/Linux、Windows、Mac OS等多种平台。
OpenSSL最早的版本在1995年发布,1998年后开始由OpenSSL项目组维护和开发。当前最新的版本是1.1.0 alpha版本,完全实现了对SSLv1、SSLv2、SSLv3和TLS的支持。。目前,OpenSSL已经得到了广泛的应用,许多类型的软件中的安全部分都使用了OpenSSL的库,如VOIP的OpenH323协议、Apache服务器、Linux安全模块等等。
基本功能
OpenSSL整个软件包大概可以分成三个主要的功能部分:
- 密码算法库
- SSL协议库
- 应用程序
密码算法库是一个强大完整的密码算法库,它是OpenSSL的基础部分,也是很值得一般密码安全技术人员研究的部分,它实现了目前大部分主流的密码算法和标准。主要包括对称算法、非对称算法、散列算法、数字签名和认证、X509数字证书标准、PKCS12、PKCS7等标准。其他两个功能部分SSL协议和应用程序都是基于这个库开发的。
在密码算法库的基础上实现的,SSL协议部分完全实现和封装了SSL协议的三个版本和TLS协议。使用协议库,你完全可以建立一个SSL服务器和SSL客户端。
应用程序是基于密码算法库和SSL协议库实现的命令,熟悉OpenSSL可以从使用这些应用程序开始。应用程序覆盖了密码技术的应用,主要包括了各种算法的加密程序和各种类型密钥的产生程序(如RSA、Md5、Enc等等)、证书签发和验证程序(如Ca、X509、Crl等)、SSL连接测试程序(如S_client和S_server等)以及其它的标准应用程序(如Pkcs12和Smime等)。
实验步骤
实验5-1
- 在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的作业
- 提交运行结果截图
Linux下OpenSSL的安装
Linux下的应用大多可以直接使用,也可以获取源代码自己进行编译、安装,使用源代码安装的过程一般是:
configure
make
make install
- 在虚拟机中打开OpenSSL官网,选择打开OpenSSL源码下载地址,在图中下载压缩包
- 首先在下载的文件夹中国进行解压
使用命令
tar xzvf openssl-1.1.0-pre1.tar.gz
然后在源代码目录文件夹下打开终端或者使用命令进入:
cd openssl-1.1.0-pre1
然后使用下列命令编译安装:
./configure
make
make install
使用make test测试一下有没有问题。
OpenSSL应用程序:通过man openssl查看帮助文档。
测试
- 测试代码
test_openssl.c:
#include <stdio.h>
#include <openssl/evp.h>
int main(){
OpenSSL_add_all_algorithms();
return 0;
}
- 使用命令编译,生成“test_openssl”可执行文件
gcc -o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread
-L选项——指定链接库的文件夹地址;-lcrypto——导入OpenSSL所需包;-ldl选项——加载动态库;-lpthread选项——链接POSIX thread库
- 运行程序,并执行
echo $?
结果打印0,测试结果表明安装成功。
基于Socket实现TCP通信,一人实现服务器,一人实现客户端
基于Linux Socket程序设计实现wc服务器和客户端
- 客户端传一个文本文件给服务器
- 服务器返加文本文件中的单词数
研究OpenSSL算法,测试对称算法中的AES,非对称算法中的RSA,Hash算法中的MD5
AES算法
对称加密:对称加密需要使用的标准命令为 enc
openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64]
[-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md]
[-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]
-in filename:指定要加密的文件存放路径
-out filename:指定加密后的文件存放路径
-salt:自动插入一个随机数作为文件内容加密,默认选项
-e:可以指明一种加密算法,若不指的话将使用默认加密算法
-d:解密,解密时也可以指定算法,若不指定则使用默认算法,但一定要与加密时的算法一致
-a/-base64:使用-base64位编码格式
openssl enc -aes-128-cbc -in my.txt -out out.txt -pass pass:123456
RSA:
RSA 的用法如下:
openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin arg] [-out filename] [-passout arg]
[-sgckey] [-des] [-des3] [-idea] [-text] [-noout] [-modulus] [-check] [-pubin] [-pubout] [-engine id]
常用选项:
-in filename:指明私钥文件
-out filename:指明将提取出的公钥保存至指定文件中
-pubout:根据私钥提取出公钥
RSA是一个非对称加密算法。简单说来,非对称加密算法就是说加密解密一个文件需要有两个密钥,一个用来加密,为公钥,一个用来解密,为私钥。证书可以用来授权公钥的使用。
- 首先需要进入openssl的交互界面,在命令行了输入
openssl
即可;
生成RSA私钥:
genrsa -out rsa_private_key.pem 1024
该命令会生成1024位的私钥,生成成功的界面如下:
此时我们就可以在当前路径下看到rsa_private_key.pem文件了。
生成RSA公钥
输入命令
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
并回车,得到生成成功的结果,如下图:
加密文件
在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件:
openssl rsautl -encrypt -in hello.txt -inkey rsa_public_key.pem -pubin -out hello.e
-in指定要加密的文件,
-inkey指定密钥,
-pubin表明是用纯公钥文件加密,
-out为加密后的文件。
解密文件:
使用命令
openssl rsautl -decrypt -in hello.e -inkey rsa_private_key.pem -out hello.de
-in指定被加密的文件,
-inkey指定私钥文件,
-out为解密后的文件。
MD5
- 用oppnssl md5 加密字符串和文件的方法。
- oppnssl md5 加密字符串的方法
在终端中输入openssl后回车。
OpenSSL> md5 //输入md5后回车
hello iam genius duanzhuazhua //接着输入明文,不要输入回车。然后按3次ctrl+d。
hello iam genius duanzhuazhua(stdin)= 409af646870cb6fc4d827616d91a86f5
//等号后面就是密文
实验5-2
在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
提交测试截图
头文件:
#include <openssl/ssl.h>
#include <openssl/err.h>
SSL库初始化
SSL_library_init();
载入所有 SSL 算法
OpenSSL_add_all_algorithms();
载入所有 SSL 错误消息
SSL_load_error_strings();
产生一个 SSL_CTX
ctx = SSL_CTX_new(SSLv23_server_method());
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);
}
基于 ctx 产生一个新的 SSL,并将连接用户的 socket 加入到 SSL
ssl = SSL_new(ctx);
SSL_set_fd(ssl, new_server_socket_fd);
建立 SSL 连接
if (SSL_accept(ssl) == -1) {
perror("accept");
close(new_fd);
break;
}
SSL数据传输
int len = SSL_read(ssl, buffer, MAXBUF);
if (len > 0)
printf("接收消息成功:‘%s‘,共%d个字节的数据\n", buffer, len);
else
printf("消息接收失败!错误代码是%d,错误信息是‘%s‘\n",errno, strerror(errno));
客户端与服务器传输完数据后,关闭 SSL 连接,释放 SSL
SSL_shutdown(ssl);
SSL_free(ssl);
释放 CTX
SSL_CTX_free(ctx);
客户端码云链接
服务器码云链接
生成的证书和私钥
- 使用命令进行编译:
gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread
gcc -o telent telent.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread
- 生产私钥和证书
openssl genrsa -out privkey.pem 1024
openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095
- 程序运行方式:
./server 7838 1 CAcert.pem privkey.pem
./telent 127.0.0.1 7838
实验中的问题及解决过程
问题1:在使用下面命令安装编译时出现下图错误:
./configure
make
make install
解决:
在命令
make install
前面加上
sudo
即可。
问题2:使用命令编译,test_openssl文件,报错信息如下:
gcc -o to test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread
解决:
在/usr/local/ssl路径下创建lib文件夹,然后把openssl_master目录下所有*.a文件复制到/usr/local/ssl/lib路径下:
sudo cp /home/下载/openssl-master/*.a /usr/local/ssl/lib
并且将原命令中的to 去掉,即可编译成功,命令如下:
gcc -o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread
编译成功:
问题3
在MD5加密中为什么在输入明文后不回车呢?
解决
是因为openssl默认会把回车符当做要加密的字符串中的一个字符,所以得到的结果不同。如果你输入明文后回车,在按2次ctrl+d。得到的结果是:
==上面是正确结果==,下面是输入回车后的错误结果:
知识点
- OpenSSL 是一个开源项目,其组成主要包括一下三个组件:
openssl:多用途的命令行工具
libcrypto:加密算法库
libssl:加密模块应用库,实现了ssl及tls
- OpenSSL对于随机数的生成和管理也提供了一整套的解决方法
- openssl口令生成密钥的API,和证书签发
- openssl子命令,分为三类:
标准命令
消息摘要(dgst子命令)
加密命令(enc子命令)
- RSA是一个非对称加密算法,需要有两个密钥,一个用来加密,为公钥,一个用来解密,为私钥。
- 证书可以用来授权公钥的使用。
- openssl命令分类
实验体会
对于OpenSSL的使用我是第一次接触,很多都不是很熟悉,需要上网查询有关资料。通过查询资料,了解了很多的知识点和方法,也了解了其背后的原理,总之就是通过实践掌握了很多知识,也收获了很多。