一、生成CA证书文件

  1. 创建CA的私钥:
1
openssl genrsa -out ca.key 2048
  1. 创建根证书签名请求文件ca.csr

    证书申请者在生成私钥的同时也生成证书请求文件。把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书

1
openssl req -new -out ca.csr -key ca.key

根据提示输入相关信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:ShenZhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bat
Organizational Unit Name (eg, section) []:bat
Common Name (e.g. server FQDN or YOUR name) []:nebula_ca
## Common Name,ca证书不要跟clien和server两方命名相同
Email Address []:
A challenge password []: ****
An optional company name []:
  1. 自签根证书ca.crt(或ca.cer、ca.pem):
1
openssl x509 -req -in ca.csr -out ca.crt -signkey ca.key -CAcreateserial -days 3650
1
2
3
Signature ok
subject=C = CN, ST = GuangDong, L = ShenZhen, O = sibat, OU = sibat, CN = nebula_ca
Getting Private key

crt、cer、pem、der区别

证书根据编码规则不同,分为:

  • pem:使用ASCII(Base64)编码后的文件。当使用文本编辑器打开后,会看到“—–BEGIN CERTIFICATE”开头的信息。

  • der:使用二进制编码的文件。

根据不同平台需要,对证书扩展出了cer和crt。他们可以是ASCII格式的pem,也可以是二进制的der。

.crt后缀,用于在linux、unix系统中,.cer后缀多用于windows系统中。本质上可以划等号,大部分场景下,甚至可以直接互相修改后缀,也能正确运作。

正确的pem证书查看方式:

1
openssl x509 -in ca.crt -text -noout

正确的der证书查看方式:

1
openssl x509 -in ca.der -inform der -text -noout

二、生成服务端证书

  1. 生成服务端私钥
1
openssl genrsa -out server.key 2048
  1. 生成服务端请求文件 server.csr
1
openssl req -new -out server.csr -key server.key

根据提示输入相关信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:ShenZhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bat
Organizational Unit Name (eg, section) []:bat
Common Name (e.g. server FQDN or YOUR name) []:nebule_server
## 理论上,需要使用服务器域名,不然双向认证下,客户端认证服务端证书时,请求域名跟Common Name不一致,导致认证失败。可以使用通配符比如*.test.com
Email Address []:
A challenge password []:***
An optional company name []:
  1. 生成服务端证书server.crt
1
openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650

三、生成客户端证书

  1. 生成客户端私钥
1
openssl genrsa -out client.key 2048
  1. 生成服务端请求文件 client.csr
1
openssl req -new -out client.csr -key client.key

根据提示输入相关信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GuangDong
Locality Name (eg, city) []:ShenZhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:sibat
Organizational Unit Name (eg, section) []:sibat
Common Name (e.g. server FQDN or YOUR name) []:nebule_client
# Common Name客户端名称随意,无影响
Email Address []:
A challenge password []:sibat@2022
An optional company name []:
  1. 生成服务端证书server.crt
1
openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650

四、NGINX配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      server.crt; # 服务端证书
        ssl_certificate_key  server.key; # 服务端私钥
        ssl_client_certificate  ca.crt; # ca证书,用于认证客户端证书合法性
        ssl_verify_depth 1; # 验证深度,如果中级CA签发的证书要通过认证,需要增加该值
        ssl_verify_client on; # 开启客户端验证

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5; #允许的密码,openssl ciphers查看支持格式
        ssl_prefer_server_ciphers  on; #是否服务器密码优先于客户端密码

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

五、请求验证

  1. curl方式:
1
2
3
4
curl -vvvv --cacert ca.crt --cert client.crt --key client.key "https://127.0.0.1"
# --cacert ca证书
# --cert 客户端证书
# --key 客户端私钥

默认情况下,客户端会校验服务端证书,并且会对比请求host和服务端证书中Common name是否一致,如果不一致,则认为校验失败。如果不需要校验服务端证书,可以增加 -k

1
2
curl -k -vvvv --cacert ca.crt --cert client.crt --key client.key "https://127.0.0.1"
# -k 忽略校验服务端证书。
  1. PostMan方式:

    在SETTINGS –> Certificates中,配置相应的ca证书和客户端证书

image-20220623142600329

​ SEETINGS –> General中,设置是否验证服务端证书,如果验证,则必须保证在上一步有正确配置CA证书。

image-20220623143004833