基于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.cnfopenssl.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.keyca.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.csrmyserver.keycsr即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设置密钥相关的几个参数即可。

原文地址:https://www.cnblogs.com/thammer/p/13751146.html