关于Thrift和OpenSSL的安全通信,上篇我们描述了zlib的编译方法,本文编译libevent库。
- 01#编译OpenSSL库;
- 02#编译Boost库;
- 03#编译zlib库;
- 04#编译libevent库;
- 05#编译Thrift库;
- 06#生成客户端和服务端通信所用的数字证书;
- 07#编写基于Linux系统的测试代码(单向验证:客户端验证服务端);
- 08#编写基于Windows系统的测试代码(单向验证:客户端验证服务端);
- 09#编写基于Linux系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
- 10#编写基于Windows系统的测试代码(双向验证:客户端验证服务端+服务端验证客户端);
- 11#自定义数字证书的验证策略;
我们知道x509数字证书有V1和V3版本,对于我们来说采用V1版本即可,考虑到证书生成的便捷性,推荐使用如下的第二种方法生成我们需要的证书。
证书生成方法1:交互模式生成证书-V1版本
第一步,将下述内容保存为文件,名称可以为openssl.cnf,后续在使用openssl命令时将使用到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| [req] distinguished_name = req_distinguished_name
[req_distinguished_name] countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2
stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company) 0.organizationName_default = Internet Widgits Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64
emailAddress = Email Address emailAddress_max = 64
|
第二步,使用如下命令创建根证书的私钥和公钥证书文件:
1 2 3 4 5
| openssl genrsa -out ca.key 2048
openssl req -new -config openssl.cnf -key ca.key -out ca.csr
openssl x509 -req -days 3650 -sha256 -signkey ca.key -in ca.csr -out ca.crt
|
上述命令执行过程如下图所示:

第三步,使用如下命令创建服务端证书的私钥和公钥证书文件:
1 2 3 4 5
| openssl genrsa -out server.key 2048
openssl req -new -config openssl.cnf -key server.key -out server.csr
openssl x509 -req -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
|
上述命令执行过程如下图所示:

第四步,使用如下命令创建客户端证书的私钥和公钥证书文件:
1 2 3 4 5
| openssl genrsa -out client.key 2048
openssl req -new -config openssl.cnf -key client.key -out client.csr
openssl x509 -req -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt
|
上述命令执行过程如下图所示:

上述命令执行完毕,我们可以在当前目录看到如下文件:

证书生成方法2:非交互模式生成证书-V1版本(该方法是本系列推荐的方法,比较简单实用)
第一步,将下述内容保存为文件,名称可以为min.cnf,后续在使用openssl命令时将使用到。
1 2 3 4
| [req] distinguished_name = req_distinguished_name
[req_distinguished_name]
|
第二步,使用如下命令创建根证书的私钥和公钥证书文件:
1 2 3 4 5 6
| ##R1) 根证书的生成命令 openssl genrsa -out ca.key 2048
openssl req -new -config min.cnf -key ca.key -out ca.csr -subj "/C=CN/ST=ShanDong/L=JiNan/O=RootCA/OU=RootSign/CN=RootSignEV/emailAddress=ca@root.com"
openssl x509 -req -days 3650 -sha256 -signkey ca.key -in ca.csr -out ca.crt
|
第三步,使用如下命令创建服务端证书的私钥和公钥证书文件:
1 2 3 4 5 6 7 8 9 10
| ##S1) 服务端证书生成命令: openssl genrsa -out server.key 2048
openssl req -new -config min.cnf -key server.key -out server.csr -subj "/C=CN/ST=GuangDong/L=ShenZhen/O=Mancode/OU=MIG/CN=127.0.0.1/emailAddress=server@mancode.net"
##S2) 根证书对服务端证书进行签名,命令: openssl x509 -req -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
##S3) 服务端证书的验证,命令: openssl verify -CAfile ca.crt server.crt
|
第四步,使用如下命令创建客户端证书的私钥和公钥证书文件:
1 2 3 4 5 6 7 8 9 10
| ##C1) 客户端证书生成命令: openssl genrsa -out client.key 2048
openssl req -new -config min.cnf -key client.key -out client.csr -subj "/C=CN/ST=HuBei/L=WuHan/O=SanXian/OU=RD/CN=127.0.0.1/emailAddress=client@sanxian.site"
##C2) 根证书对客户端证书进行签名,命令: openssl x509 -req -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt
##C3) 客户端证书的验证,命令: openssl verify -CAfile ca.crt client.crt
|
依次使用上述命令,执行过程如下图所示:

上述命令执行完毕,我们可以在当前目录看到如下文件:

双击各数字证书文件,我们查看下证书的使用者信息:
这里简单介绍一下,使用者信息中的各种简写参数的含义:
| 证书中的参数简写 | openssl命令参数 | 含义 | 备注 |
| C | C | Country Name (2 letter code) | 国家代码(2位) |
| S | ST | State or Province Name (full name) | 省份/州 |
| L | L | Locality Name (eg, city) | 城市名称 |
| O | O | Organization Name (eg, company) | 公司/组织名称 |
| OU | OU | Organizational Unit Name (eg, section) | 部门名称 |
| CN | CN | Common Name (e.g. server FQDN or YOUR name) | 通用名称,通常是域名/个人姓名/IP地址 |
| E | emailAddress | Email Address | 邮箱地址 |
至此,使用当前方法已生成了客户端和服务端通信用的数字证书,各证书的具体的使用方法,我们将在后文介绍。
证书生成方法3:非交互模式生成证书-V3版本
第一步,将下述内容保存为文件,名称可以为openssl.cnf,后续在使用openssl命令时将使用到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| [req] prompt = no default_bits = 2048 distinguished_name = req_distinguished_name x509_extensions = v3_ca req_extensions = v3_req
[v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alternate_names
[alternate_names] IP.1=127.0.0.1 IP.2=::1 IP.3=::ffff:127.0.0.1 DNS.1=localhost
[v3_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:TRUE, pathlen:0 keyUsage = critical, cRLSign, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alternate_names
[req_distinguished_name]
|
第二步,使用如下命令,依次生成根证书、服务端证书、客户端证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ##R1) 根证书的生成命令 openssl genrsa -out ca.key 2048
openssl req -new -config openssl.cnf -key ca.key -out ca.csr -subj "/C=CN/ST=ShanDong/L=JiNan/O=RootCA/OU=RootSign/CN=RootSignEV/emailAddress=ca@root.com"
openssl x509 -req -extfile openssl.cnf -days 3650 -sha256 -signkey ca.key -in ca.csr -out ca.crt -extensions v3_req -extensions v3_ca
##S1) 服务端证书生成命令: openssl genrsa -out server.key 2048
openssl req -new -config openssl.cnf -key server.key -out server.csr -subj "/C=CN/ST=GuangDong/L=ShenZhen/O=Mancode/OU=MIG/CN=127.0.0.1/emailAddress=server@mancode.net"
##S2) 根证书对服务端证书进行签名,命令: openssl x509 -req -extfile openssl.cnf -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -extensions v3_req -extensions v3_ca
##S3) 服务端证书的验证,命令: openssl verify -CAfile ca.crt server.crt
##C1) 客户端证书生成命令: openssl genrsa -out client.key 2048
openssl req -new -config openssl.cnf -key client.key -out client.csr -subj "/C=CN/ST=HuBei/L=WuHan/O=SanXian/OU=RD/CN=127.0.0.1/emailAddress=client@sanxian.site"
##C2) 根证书对客户端证书进行签名,命令: openssl x509 -req -extfile openssl.cnf -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -extensions v3_req -extensions v3_ca
##C3) 客户端证书的验证,命令: openssl verify -CAfile ca.crt client.crt
|
依次使用上述命令,执行过程如下图所示:

上述命令执行完毕,我们可以在当前目录看到如下文件:

证书生成方法4:非交互模式生成证书-基于配置文件-V3版本
第一步,将下述内容保存为:rootca.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| [req] prompt = no default_bits = 2048 distinguished_name = req_distinguished_name x509_extensions = v3_ca req_extensions = v3_req
[v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alternate_names
[alternate_names] IP.1=127.0.0.1 IP.2=::1 IP.3=::ffff:127.0.0.1 DNS.1=localhost
[v3_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:TRUE, pathlen:0 keyUsage = critical, cRLSign, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alternate_names
[req_distinguished_name] C = CN ST = ShanDong L = JiNing O = RootCA OU = RootSign CN = RootSignEV emailAddress = ca@rootca.com
|
第二步,将下述内容保存为:server.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| [req] prompt = no default_bits = 2048 distinguished_name = req_distinguished_name x509_extensions = v3_ca req_extensions = v3_req
[v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alternate_names
[alternate_names] IP.1=127.0.0.1 IP.2=::1 IP.3=::ffff:127.0.0.1 DNS.1=localhost
[v3_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:TRUE, pathlen:0 keyUsage = critical, cRLSign, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alternate_names
[req_distinguished_name] C = CN ST = GuangDong L = ShenZhen O = Mancode OU = MIG CN = 127.0.0.1 emailAddress = server@mancode.net
|
第三步,将下述内容保存为:client.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| [req] prompt = no default_bits = 2048 distinguished_name = req_distinguished_name x509_extensions = v3_ca req_extensions = v3_req
[v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alternate_names
[alternate_names] IP.1=127.0.0.1 IP.2=::1 IP.3=::ffff:127.0.0.1 DNS.1=localhost
[v3_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:TRUE, pathlen:0 keyUsage = critical, cRLSign, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alternate_names
[req_distinguished_name] C = CN ST = HuBei L = WuHan O = SanXian OU = RD CN = 127.0.0.1 emailAddress = client@sanxian.site
|
第四步,使用如下命令,依次生成根证书、服务端证书、客户端证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ##R1) 根证书的生成命令: openssl genrsa -out ca.key 2048
openssl req -new -config rootca.cnf -key ca.key -out ca.csr
openssl x509 -req -extfile rootca.cnf -days 3650 -sha256 -signkey ca.key -in ca.csr -out ca.crt -extensions v3_req -extensions v3_ca
##S1) 服务端证书生成命令: openssl genrsa -out server.key 2048
openssl req -new -config server.cnf -key server.key -out server.csr
##S2) 根证书对服务端证书进行签名,命令: openssl x509 -req -extfile server.cnf -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -extensions v3_req -extensions v3_ca
##S3) 服务端证书的验证,命令: openssl verify -CAfile ca.crt server.crt
##C1) 客户端证书生成命令: openssl genrsa -out client.key 2048
openssl req -new -config client.cnf -key client.key -out client.csr
##C2) 根证书对客户端证书进行签名,命令: openssl x509 -req -extfile client.cnf -days 3650 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt -extensions v3_req -extensions v3_ca
##C3) 客户端证书的验证,命令: openssl verify -CAfile ca.crt client.crt
|
依次使用上述命令,执行过程如下图所示:

上述命令执行完毕,我们可以在当前目录看到如下文件:

双击各数字证书文件,我们查看下证书的使用者信息: