如何生成和使用自签名证书

1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

环境介绍

操作系统IP地址主机名NGINX版本角色
Rocky9.4192.168.8.3loadbalance.xiaohui.cn1.26.2负载均衡

引言

在互联网安全性日益重要的今天,使用 SSL/TLS 证书来加密数据传输已经成为保护用户隐私和数据完整性的标准做法。自签名证书是一种简便的方法,用于开发、测试和内部应用中,提供加密通信,而不依赖于第三方认证机构(CA)。尽管自签名证书在生产环境中的使用受限,但它们在许多场景中依然具有重要价值。

我这个文章主要演示如何生成和使用自签名证书,帮助你在实际项目中更好地理解和应用这一技术。通过详细的步骤和示例,我将带你一步步完成从生成私钥到配置 Web 服务器使用自签名证书的整个过程。

什么是自签名证书?

自签名证书是一种由用户自己创建并签署的 SSL/TLS 证书。与由认证机构(CA)签发的证书不同,自签名证书不依赖于第三方的验证和信任链,完全用自己的资源实现。

优势

  1. 成本低:生成自签名证书是免费的,不需要支付认证机构的费用。

  2. 立即可用:不需要等待第三方审核和签发,可以立即生成和使用。

  3. 适用于开发和测试:在开发和测试环境中,自签名证书提供了便捷的加密解决方案。

劣势

  1. 信任问题:由于自签名证书没有经过第三方认证机构的验证,浏览器会警告用户该证书不被信任,可能会影响用户体验,需要在用户端导入根证书才可以解决警告问题。

  2. 受限于内部使用:适用于开发、测试和内部应用,不建议在生产环境中使用。

通过理解自签名证书的概念和工作原理,我们可以更好地在合适的场景中应用它们。在接下来的部分中,我们将详细介绍如何生成和使用自签名证书。

生成根证书颁发机构(CA)

有的人直接就生成服务器证书,这是不对的,我们需要先生成根证书颁发机构,然后用这个CA去签名证书,以后我们可以让客户端信任这个CA,所有用这个CA生产的证书都会自动信任。

这条命令生成一个 4096 位的 RSA 私钥,并将其存储在 /etc/pki/tls/private/selfsignroot.key 文件中。私钥是用于签署证书的核心部分。

1
openssl genrsa -out /etc/pki/tls/private/selfsignroot.key 4096
1
2
3
openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Shanghai/L=Shanghai/O=Company/OU=SH/CN=Root" \
-key /etc/pki/tls/private/selfsignroot.key \
-out /etc/pki/ca-trust/source/anchors/selfsignroot.crt

上面这条命令生成一个自签名证书,并将其存储在 /etc/pki/ca-trust/source/anchors/selfsignroot.crt 文件中。以下是各参数的解释:

  • -x509:生成一个自签名证书,而不是证书请求(CSR)。

  • -new:生成一个新的证书。

  • -nodes:不加密私钥文件。

  • -sha512:使用 SHA-512 哈希算法。

  • -days 3650:证书有效期为 3650 天(约 10 年)。

  • -subj "/C=CN/ST=Shanghai/L=Shanghai/O=Company/OU=SH/CN=Root":指定证书的主题信息,包括国家(C)、州/省(ST)、城市(L)、组织(O)、组织单位(OU)和通用名称(CN)。

  • -key /etc/pki/tls/private/selfsignroot.key:使用之前生成的私钥。

  • -out /etc/pki/ca-trust/source/anchors/selfsignroot.crt:指定输出的证书文件路径。

用openssl命令查询证书文件,当然,你可以复制到Windows上,直接双击也可以看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@loadbalance ~]# openssl x509 -in /etc/pki/ca-trust/source/anchors/selfsignroot.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
42:cf:93:26:cb:ec:36:52:de:f1:28:a8:fd:46:93:81:86:9d:03:da
Signature Algorithm: sha512WithRSAEncryption
Issuer: C=CN, ST=Shanghai, L=Shanghai, O=Company, OU=SH, CN=Root
Validity
Not Before: Jan 20 07:47:18 2025 GMT
Not After : Jan 18 07:47:18 2035 GMT
Subject: C=CN, ST=Shanghai, L=Shanghai, O=Company, OU=SH, CN=Root
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
...

运行以下命令来更新 CA 信任存储库,使系统信任新的根证书:

1
update-ca-trust extract

签发服务器证书

生成服务器私钥文件

1
openssl genrsa -out /etc/pki/tls/private/nginx.key 4096

生成证书请求文件

我们来尝试给loadbalance.xiaohui.cn域名申请一个证书

1
2
3
4
openssl req -sha512 -new \
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=Company/OU=SH/CN=loadbalance.xiaohui.cn" \
-key /etc/pki/tls/private/nginx.key \
-out nginx.csr
  • openssl req -sha512 -new:使用 SHA-512 哈希算法生成一个新的 CSR。

  • -subj "/C=CN/ST=Shanghai/L=Shanghai/O=Company/OU=SH/CN=loadbalance.xiaohui.cn":指定 CSR 的主题信息,包括:

    • /C=CN:国家代码,CN 表示中国。

    • /ST=Shanghai:州/省,Shanghai 表示上海。

    • /L=Shanghai:城市,Shanghai 表示上海。

    • /O=Company:组织名称,Company 表示公司。

    • /OU=SH:组织单位,SH 表示上海分部。

    • /CN=loadbalance.xiaohui.cn:通用名称,表示证书的域名。

  • -key /etc/pki/tls/private/nginx.key:使用之前生成的私钥,存储在 /etc/pki/tls/private/nginx.key 文件中。

  • -out nginx.csr:指定输出的 CSR 文件路径为 nginx.csr

除了这种简单的申请之外,还可以生成扩展文件,以支持更多的证书属性,最常用的是给多个域名或IP同时验证合法身份,也就是给证书添加备用名称

  • DNS.1 = web1.xiaohui.cn:指定第一个 DNS 名称为 web1.xiaohui.cn

  • DNS.2 = web2.xiaohui.cn:指定第二个 DNS 名称为 web2.xiaohui.cn

  • IP.1 = 192.168.8.3:指定第一个 IP 地址为 192.168.8.3

  • IP.2 = 192.168.8.4:指定第二个 IP 地址为 192.168.8.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat > certs.cnf << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = web1.xiaohui.cn
DNS.2 = web1.xiaohui.cn
IP.1 = 192.168.8.3
IP.2 = 192.168.8.4
EOF

最终签发证书

命令解释

  1. openssl x509 -req -in nginx.csr

    • 使用 CSR(nginx.csr)生成证书。

    • -req:表明输入是一个证书签名请求。

  2. -CA /etc/pki/ca-trust/source/anchors/selfsignroot.crt

    • 使用自签名根证书(selfsignroot.crt)作为 CA 来签署 CSR。
  3. -CAkey /etc/pki/tls/private/selfsignroot.key

    • 使用自签名根证书对应的私钥(selfsignroot.key)进行签署。
  4. -CAcreateserial

    • 自动创建序列号文件。如果没有指定 -CAserial 文件,这个选项将创建一个新的序列号文件。
  5. -out /etc/pki/tls/certs/nginx.crt

    • 指定生成的服务器证书输出路径为 nginx.crt
  6. -days 3650

    • 指定证书的有效期为 3650 天(约 10 年)。
  7. -extensions v3_req -extfile certs.cnf

    • 使用 certs.cnf 文件中定义的 v3_req 扩展来生成证书。这确保了证书包含你在 certs.cnf 文件中指定的扩展,例如 subjectAltName
1
2
3
4
5
openssl x509 -req -in nginx.csr \
-CA /etc/pki/ca-trust/source/anchors/selfsignroot.crt \
-CAkey /etc/pki/tls/private/selfsignroot.key -CAcreateserial \
-out /etc/pki/tls/certs/nginx.crt \
-days 3650 -extensions v3_req -extfile certs.cnf

输出

1
2
Certificate request self-signature ok
subject=C=CN, ST=Shanghai, L=Shanghai, O=Company, OU=SH, CN=loadbalance.xiaohui.cn

我们来检查一下,证书是否包括多个域名和IP

没有问题,这个证书同时给多个域名和IP验证

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
[root@loadbalance ~]# openssl x509 -in /etc/pki/tls/certs/nginx.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1b:21:cf:35:e8:4a:b0:0a:6c:32:74:5c:84:44:f3:46:f4:25:fc:08
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=Shanghai, L=Shanghai, O=Company, OU=SH, CN=Root
Validity
Not Before: Jan 20 07:59:24 2025 GMT
Not After : Jan 18 07:59:24 2035 GMT
Subject: C=CN, ST=Shanghai, L=Shanghai, O=Company, OU=SH, CN=loadbalance.xiaohui.cn
Subject Public Key Info:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:web1.xiaohui.cn, DNS:web1.xiaohui.cn, IP Address:192.168.8.3, IP Address:192.168.8.4
X509v3 Subject Key Identifier:
9B:4C:C5:2C:ED:67:02:CD:B2:18:61:92:57:F6:46:FF:B2:74:80:1C
X509v3 Authority Key Identifier:
FA:68:94:CE:7C:B3:69:2D:4C:A9:86:8C:66:22:24:6C:32:33:3B:72