基于自签名 CA 实现 Nginx 与 浏览器的双向认证与加密通信

双向 TLS 认证,是一种安全机制,提供了更高级别的安全性,适用于需要严格身份验证和数据保护的场景。

主要特性如下

  • 防范中间人攻击: 双向认证可以防止中间人攻击,因为攻击者无法伪造有效的客户端证书。这对于保护数据在传输过程中的完整性和机密性至关重要
  • 限制访问: 双向认证允许服务器仅允许特定的客户端连接。这对于内部服务、管理接口或特定用户群体的访问控制非常有用

环境介绍

1、系统及组件版本信息

[root@x9 ~]# openssl version
#> OpenSSL 1.0.2k-fips  26 Jan 2017
[root@x9 ~]#
[root@x9 ~]# cat /etc/redhat-release
#> CentOS Linux release 7.9.2009 (Core)
[root@x9 ~]#
[root@x9 ~]# uname -r
#> 3.10.0-1160.el7.x86_64

2、本文涉及的相关证书及信息

# 根证书
#> ca-cert.pem
#> ca-key.pem
# client 端证书
#> example.com-client-key.pem
#> example.com-client-csr.pem
#> example.com-client-cert.pem
#> example.com-client.p12
# Server 端证书
#> example.com-key.pem
#> example.com-csr.pem
#> example.com-cert.pem
#> example.com-pub-key.pem

TLS 认证流程图

TLS 加密通信单向及双向认证流程架构图
TLS 加密通信单向及双向认证流程架构图

OpenSSL.conf

openssl.cnf 文件是 OpenSSL 用来存储配置信息的文件,它可以用来配置证书签名请求(CSR)和数字证书生成过程中使用的各种选项,例如域名证书中的各种信息和扩展

1、编辑 vim /etc/pki/tls/openssl.cnf,添加 x509 v3 扩展信息到证书签名文件

[ req ]
………………
# 去除注释,启用 req_extensions
req_extensions = v3_req     # The extensions to add to a certificate request
………………

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# 添加如下行
subjectAltName = @san_names

# 同时增加如下信息
[san_names]
DNS.1   = example.com
DNS.2   = *.example.com     # 通配符证书,或泛域名证书
# IP.1    = 192.168.31.11
# IP.2    = 192.168.31.12

创建根证书

# 创建 CA 私钥 ca-key.pem
openssl genrsa -out ca-key.pem 2048

# 创建 CA 证书 ca-cert.pem
openssl req -sha256 -new -x509 -days 36500 -key ca-key.pem -out ca-cert.pem -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Mycompany/OU=JiaWen/CN=JiaWen-CA/emailAddress=admin@163.com"  -config /etc/pki/tls/openssl.cnf

创建服务器证书

1、编辑 vim /etc/pki/tls/openssl.cnf,注释 clientAuth ,启用 serverAuth

[ v3_req ]
extendedKeyUsage = serverAuth       # TLS Web Server Authentication  保证远程计算机的身份
# extendedKeyUsage = clientAuth
# 生成域名私钥
openssl genrsa -out example.com-key.pem 2048

# 生成证书签发请求文件,可以使用证书签名请求文件向证书颁发机构申请数字证书
# common name 一定要在 SubjectAlternativeName 中包含
openssl req -new -sha256 -key example.com-key.pem -out example.com-csr.pem -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Mycompany/OU=JiaWen/CN=*.example.com/emailAddress=admin@163.com" -config /etc/pki/tls/openssl.cnf

# 使用自签署的 CA,生成域名证书(包含域名公钥、域名信息、CA 签名)
# 进行 CA 签名获取证书时,需要注意国家、省、单位需要与 CA 证书相同,否则会报异常 !! 不过可用通过 openssh.cnf 调整配置 policy_match
openssl ca -in example.com-csr.pem -md sha256 -days 36500 -cert ca-cert.pem -keyfile ca-key.pem -extensions v3_req -out example.com-cert.pem -config /etc/pki/tls/openssl.cnf
#> Using configuration from /etc/pki/tls/openssl.cnf
#> Check that the request matches the signature
#> Signature ok
#> Certificate Details:
#>         Serial Number: 1 (0x1)
#>         Validity
#>             Not Before: Oct 18 08:18:13 2023 GMT
#>             Not After : Sep 24 08:18:13 2123 GMT
#>         Subject:
#>             countryName               = CN
#>             stateOrProvinceName       = SiChuan
#>             organizationName          = Mycompany
#>             organizationalUnitName    = JiaWen
#>             commonName                = *.example.com
#>             emailAddress              = admin@163.com
#>         X509v3 extensions:
#>             X509v3 Basic Constraints:
#>                 CA:FALSE
#>             X509v3 Key Usage:
#>                 Digital Signature, Non Repudiation, Key Encipherment
#>             X509v3 Extended Key Usage:
#>                 TLS Web Server Authentication
#>             X509v3 Subject Alternative Name:
#>                 DNS:example.com, DNS:*.example.com
#> Certificate is to be certified until Sep 24 08:18:13 2123 GMT (36500 days)
#> Sign the certificate? [y/n]:y
#>
#> 1 out of 1 certificate requests certified, commit? [y/n]y
#> Write out database with 1 new entries
#> Data Base Updated

openssl pkcs12 -export -in example.com-cert.pem -inkey example.com-key.pem -out example.com.p12

创建客户端证书(可选)

1、编辑 vim /etc/pki/tls/openssl.cnf,注释 serverAuth ,启用 clientAuth

[ v3_req ]
# extendedKeyUsage = serverAuth
extendedKeyUsage = clientAuth       # TLS Web Client Authentication 向远程计算机证明你的身份

2、创建客户端私钥及证书,并将二者转换为 p12 格式证书,最后将证书 example.com-client.p12 导入到浏览器端的" 个人 "证书存储位置即可

openssl genrsa -out example.com-client-key.pem 2048

# CN=192.168.31.219 可任意,标识该证书
openssl req -new -sha256 -key example.com-client-key.pem -out example.com-client-csr.pem -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Mycompany/OU=JiaWen/CN=192.168.31.219/emailAddress=admin@163.com" -config /etc/pki/tls/openssl.cnf

# 使用 ca 签发证书
openssl ca -in example.com-client-csr.pem -md sha256 -days 36500 -cert ca-cert.pem -keyfile ca-key.pem -extensions v3_req -out example.com-client-cert.pem -config /etc/pki/tls/openssl.cnf

# 将证书及私钥合并为 p12 格式的证书 example.com-client.p12。提示设置密码,可直接回车,则密码为空
openssl pkcs12 -export -in example.com-client-cert.pem -inkey example.com-client-key.pem -out example.com-client.p12
#> Enter Export Password:
#> Verifying - Enter Export Password:

3、当启用 Nginx Client 认证后,且浏览器端未导入客户端证书及私钥时,访问 https://mobile.example.com/ 将提示如下错误:

400 Bad Request
No required SSL certificate was sent
nginx/1.24.0

安装 Nginx 服务

1、安装 Nginx

# cat /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

# 安装 Nginx
yum install nginx -y

2、修改配置

# cat /etc/nginx/conf.d/default.conf
server {
    listen       443 ssl;
    server_name  example.com www.example.com mobile.example.com;

    ssl_certificate     /etc/nginx/ssl/example.com-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com-key.pem;
    ssl_protocols      TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    # 启用 client 端验证,并设置根证书
    ssl_verify_client on;
    ssl_client_certificate /etc/nginx/ssl/ca-cert.pem;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

}

测试系统 Windows 设置

1、将自签名根证书 ca-cert.pem 导入到系统" 受信任的根证书颁发机构 "中,然后重启浏览器,这样每次通过浏览器访问该域名时,就不再提示 https 不安全等信息 !!

2、cat 添加 hosts 解析记录

192.168.31.89  example.com
192.168.31.89  www.example.com
192.168.31.89  mobile.example.com

3、启用 client 身份验证时,每次重启浏览器,访问站点 *.example.com,浏览器都会弹框提示,选择安装在浏览器端的 client 端证书 (该证书必须为 p12 格式) !!!

常用证书管理(可选)

查看 ca 根证书

使用命令openssl x509 -text -in ca-cert.pem -noout查看

#> Certificate:
#>     Data:
#>         Version: 3 (0x2)
#>         Serial Number:
#>             d4:2b:90:cd:da:5a:15:d8
       # 说明签名算法为:使用哈希算法 sha256 计算消息摘要, 使用非对称加密算法 RSA 的私钥(ca)加密摘要信息
#>     Signature Algorithm: sha256WithRSAEncryption
#>         Issuer: C=CN, ST=SiChuan, L=ChengDu, O=Mycompany, OU=JiaWen, CN=JiaWen-CA/emailAddress=admin@163.com
           # 证书有效期范围
#>         Validity
#>             Not Before: Oct 18 08:45:13 2023 GMT
#>             Not After : Sep 24 08:45:13 2123 GMT
           # Subject 与 Issuer 相同,说明该证书是一个自签名证书
#>         Subject: C=CN, ST=SiChuan, L=ChengDu, O=Mycompany, OU=JiaWen, CN=JiaWen-CA/emailAddress=admin@163.com
#>         Subject Public Key Info:
               # 说明公钥算法为 rsa ,且强度为 2048
#>             Public Key Algorithm: rsaEncryption
#>                 Public-Key: (2048 bit)
#>                 Modulus:
#>                     00:dd:82:46:44:cf:f0:57:41:11:9a:83:4a:24:2a:
#>                     ...
#>                     6b:94:f3:19:78:b6:03:c5:ff:7c:96:5a:32:1c:18:
#>                     62:67
#>                 Exponent: 65537 (0x10001)
           # x509 v3 扩展配置项
#>         X509v3 extensions:
#>             X509v3 Subject Key Identifier:
#>                 F7:B9:73:65:20:E8:09:16:2E:D2:79:C5:26:B6:1B:F0:7D:7C:CA:2D
#>             X509v3 Authority Key Identifier:
#>                 keyid:F7:B9:73:65:20:E8:09:16:2E:D2:79:C5:26:B6:1B:F0:7D:7C:CA:2D
#>             X509v3 Basic Constraints:
#>                 CA:TRUE      # 说明该证书为 根证书
#>     Signature Algorithm: sha256WithRSAEncryption
#>          d7:a7:f1:57:90:81:8c:da:20:89:74:2e:8b:03:89:3d:d9:84:
#>          ...
#>          05:08:d2:53:16:51:9d:5b:05:ce:e7:ff:b2:68:1e:4d:de:a6:
#>          2e:e5:cb:68

查看 ca 签发的 server 端证书

使用命令 openssl x509 -text -in example.com-cert.pem -noout 查看

#> Certificate:
#>     Data:
#>         Version: 3 (0x2)
#>         Serial Number: 1 (0x1)
#>     Signature Algorithm: sha256WithRSAEncryption
           # Issuer 为 根证书的 subject 设置
#>         Issuer: C=CN, ST=SiChuan, L=ChengDu, O=Mycompany, OU=JiaWen, CN=JiaWen-CA/emailAddress=admin@163.com
#>         Validity
#>             Not Before: Oct 18 08:45:54 2023 GMT
#>             Not After : Sep 24 08:45:54 2123 GMT
           # 当前证书的 subject 设置
           # CN 设置 *.example.com 须在 X509v3 扩展配置项 X509v3 Subject Alternative Name 的范围内
#>         Subject: C=CN, ST=SiChuan, O=Mycompany, OU=JiaWen, CN=*.example.com/emailAddress=admin@163.com
#>         Subject Public Key Info:
#>             Public Key Algorithm: rsaEncryption
#>                 Public-Key: (2048 bit)
#>                 Modulus:
#>                     00:e7:3a:ff:6b:bd:65:98:4e:94:c9:81:e9:3f:87:
#>                     ...
#>                     43:a8:1c:a9:a7:95:99:30:82:ab:f0:98:fd:ac:ba:
#>                     67:4b
#>                 Exponent: 65537 (0x10001)
#>         X509v3 extensions:
#>             X509v3 Basic Constraints:
#>                 CA:FALSE
#>             X509v3 Key Usage:
#>                 Digital Signature, Non Repudiation, Key Encipherment
               # 说明是一个用于 tls web Server 端的认证证书,用于 client 端验证 server 身份
#>             X509v3 Extended Key Usage:
#>                 TLS Web Server Authentication
#>             X509v3 Subject Alternative Name:
#>                 DNS:example.com, DNS:*.example.com
#>     Signature Algorithm: sha256WithRSAEncryption
#>          3b:2e:d6:89:93:6b:ae:98:02:81:da:f6:60:16:b6:2d:62:d8:
#>          ...
#>          7c:97:45:e9:b3:5f:ac:30:a0:67:1a:7d:28:74:ae:0a:21:a9:
#>          be:9f:ac:75

查看 ca 签发的 client 端证书

使用命令 openssl x509 -text -in example.com-client-cert.pem -noout 查看

#> Certificate:
#>     Data:
#>         Version: 3 (0x2)
#>         Serial Number: 2 (0x2)
#>     Signature Algorithm: sha256WithRSAEncryption
#>         Issuer: C=CN, ST=SiChuan, L=ChengDu, O=Mycompany, OU=JiaWen, CN=JiaWen-CA/emailAddress=admin@163.com
#>         Validity
#>             Not Before: Oct 18 09:22:12 2023 GMT
#>             Not After : Sep 24 09:22:12 2123 GMT
           # CN 设置 192.168.31.219 为任意
#>         Subject: C=CN, ST=SiChuan, O=Mycompany, OU=JiaWen, CN=192.168.31.219/emailAddress=admin@163.com
#>         Subject Public Key Info:
#>             Public Key Algorithm: rsaEncryption
#>                 Public-Key: (2048 bit)
#>                 Modulus:
#>                     00:bc:26:13:28:21:50:0f:85:cc:4a:f8:c4:19:b5:
#>                     ...
#>                     1d:5e:a1:f1:03:5a:4e:fb:f9:93:92:6e:e5:1e:4b:
#>                     1d:77
#>                 Exponent: 65537 (0x10001)
#>         X509v3 extensions:
#>             X509v3 Basic Constraints:
#>                 CA:FALSE
#>             X509v3 Key Usage:
#>                 Digital Signature, Non Repudiation, Key Encipherment
               # 说明是一个用于 tls web Client 端的认证证书,用于 server 端验证 client 身份
#>             X509v3 Extended Key Usage:
#>                 TLS Web Client Authentication
               # 该扩展配置项需与 server 端证书的扩展配置项对应
#>             X509v3 Subject Alternative Name:
#>                 DNS:example.com, DNS:*.example.com
#>     Signature Algorithm: sha256WithRSAEncryption
#>          3f:0d:83:39:d0:62:7e:8e:e3:8a:e6:5b:78:97:29:65:ba:24:
#>          ...
#>          7a:e1:d8:69:96:c7:79:b1:c1:b5:ec:d3:dc:89:92:e6:96:f3:
#>          7d:3c:6f:42

其它命令

# 查看证书签名请求文件 example.com-csr.pem 的内容
openssl req -text -in example.com-csr.pem -noout

# 查看私钥文件 example.com-key.pem 的内容
openssl rsa -text -in example.com-key.pem -noout

# 从私钥文件 example.com-key.pem 提取公钥信息,并保存到 example.com-pub-key.pem
openssl rsa -in example.com-key.pem -out example.com-pub-key.pem -pubout

# 查看公钥文件信息
openssl rsa -text -in example.com-pub-key.pem -pubin -noout

码字不易,若觉得本文对你有用,欢迎点赞 👍、分享 🚀 ,相关技术热点时时看🔥🔥🔥​​​…

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值