基于libevent的TLS单向认证CS通信验证
准备工作
1.快速了解PKI/CA
PKI(Public Key Infrastructure)公钥基础设施
CA (Certificate Of Authority) 认证中心
2. 利用easy-rsa构建PKI
easy-rsa是OpenVPN下管理密钥的一个工具,它是以shell写成,主要是脚本调用openssl命令来实现。
ubuntu18.04 apt安装的是2.2.2版本,相关的工具脚本比较分散,ubuntu20.04使用的是3.0.6版本,相关工具都统一到了easyrsa一个脚本里面。ubuntu20.04 easy-rsa3.0.6使用教程,我的机器是ubuntu18.04,使用方法:
-
安装easy-rsa
sudo apt install easy-rsa
easy-rsa
安装在/usr/share/easy-rsa
目录,直接在此目录下操作也是可以的,但是需要root权限,不方便。一般使用make-cadir
命令来创建自己的CA目录
-
创建自己的CA目录
make-cadir myca
make-cadir
这个工具也是一个shell脚本,它干的事情就是创建你指定的目录,然后在此目录下创建一些符号链接,连接到/usr/share/easy-rsa
目录下的各文件,而对应的配置文件则直接拷贝过来。
-
设置环境
cd myca vim vars
CA制作需要的一些默认变量由vars文件设置,打开文件可以看到它就是在export一系列变量而已,根据你自己的需求修改后source它,让vars里面的变量在当前终端生效。
source ./vars
在我的机器上出现了错误
thomas@thomas-virtual-machine:~/myca$ source ./vars ************************************************************** No /home/thomas/myca/openssl.cnf file could be found Further invocations will fail ************************************************************** NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/thomas/myca/keys
未找到
openssl.cnf
文件,初始化这个目录的时候,从/usr/share/easy-rsa
目录拷贝过来的只有:openssl-0.9.6.cnf openssl-0.9.8.cnf openssl-1.0.0.cnf
我Ubuntu里面openssl的版本:
thomas@thomas-virtual-machine:~/myca$ openssl version OpenSSL 1.1.1 11 Sep 2018
所以拷贝一份
openssl-1.0.0.cnf
为openssl.cnf
cp openssl-1.0.0.cnf openssl.cnf
此外还需要生成一个随机数文件,在openssl.cnf文件里面定义了它的路径,它是为了让生成的密钥更安全。
HOME = . RANDFILE = $ENV::HOME/.rnd
手动生成这个文件:
dd if=/dev/urandom of=~/.rnd bs=2048 count=1
准备工作至此基本全部完成。
-
初始化PKI
./clean-all ./build-ca
clean-all
会清理老的keys目录,并且创建新keys目录,查看此脚本就看得到具体执行了什么,之后执行各种命令产生的文件基本都会放在keys目录里面。build-ca
脚本调用pkitool脚本,进而调用openssl。build-ca
过程交互如下,中间需要输入的大部参数已由vars在环境变量中设置好了默认值,基本一路回车即可。thomas@thomas-virtual-machine:~/myca$ ./build-ca Generating a RSA private key ..............................................................................+++++ .+++++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [US]: State or Province Name (full name) [CA]: Locality Name (eg, city) [SanFrancisco]: Organization Name (eg, company) [Fort-Funston]: Organizational Unit Name (eg, section) [MyOrganizationalUnit]: Common Name (eg, your name or your server's hostname) [Fort-Funston CA]: Name [EasyRSA]: Email Address [me@myhost.mydomain]:
它主要创建CA用的非对称密钥对文件:
ca.key
和ca.crt
。ca.key
文件就是私钥文件,ca.crt
就是证书文件,它里面包含与ca.key文件对应的公钥,证书描述信息,和签名(哈希值)。查看这两个文件,里面的内容格式基本是:-----BEGIN XXXXX----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6IPNsYGbE3ita nWfQ2I4WTojWc5XQEhRs5ciTFnc/gdxmx10MAC8tdXmxAYeOXP2ar56wy/dzvEjx .... .... -----END XXXXX-----
这种以
-----BEGIN XXXXX-----
开头,-----END XXXXX-----
结尾,中间一推字符的格式就是PEM格式,中间那堆东西其实是base64编码。存储证书和密钥之类的东西还有一种格式叫DER格式,DER格式一般是二进制。它们都是由X509标准定义的。这里介绍了各种格式。
-
3.签发server证书
根证书在本地
对于CA在本地创建,server证书创建也在同一个机器上时,使用脚本./build-key-server
./build-key-server myserver
中间会报index.txt.attr
文件找不到的错误,这好像是openssl版本带来的问题,easy-rsa 2.2.2对openssl1.1.x支持不好,这也是为什么默认的openssl配置文件里面只有openssl-1.0.0.cnf,可以不管。生成了myserver.*
文件。myserver.crt
这个文件在TLS协商过程中会被发送给客户端。
根证书不在本地(此方法生成的证书purposes有问题)
-
生成server的证书请求文件
./build-req myserver
按照你的实际情况填写信息,最终会在keys目录下新生成2个文件myserver.csr
和myserver.key
。csr
即Certificate Sign Request,证书签发请求。具体的操作是CA机构搭建好它的PKI后(PC1),需要搭建服务器的人在自己电脑上(PC2)生成证书请求文件,然后把证书请求文件发送给CA机构(PC1),CA机构使用自己的密钥处理一下这个文件,生成被他签名加密的证书发放给你(PC2)。
-
CA签发证书
./sign-req myserver
测试
使用openssl工具自带的服务器,客户端测试工具
server端:
openssl s_server -CAfile ca.crt -cert myserver.crt -key myserver.key -port 12345
client端:
openssl s_client -CAfile ca.crt -connect 127.0.0.1:12345 -verify 2
使用libevent wrapper
sudo apt install libevent-2.1-6 libevent-dev -y
测试源码https://gitee.com/thammer/libevent-socket-wrapper.git
,修改test_tcp_client.c、test_tcp_server.c设置密钥相关的几个参数即可。