Rootop 服务器运维与web架构

作为CA (Certificate Authority)机构颁发证书

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# 1、生成私钥公钥,自己作为ca。
mkdir ca && cd ca
openssl genpkey -algorithm RSA -out ca.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key ca.key -out ca.csr
 
cat <<EOF > v3_ca.ext
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
EOF
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt -days 3650 -extfile v3_ca.ext
 
用自己的私钥给自己签名,颁发者和持有者一样。有效期10年。
有了私钥和证书就可以给其它证书签名请求进行证书签发。
注意在openssl 3.x版本中如果证书中没有声明 basicConstraints = CA:TRUE,则该证书 不能被视为有效的 CA。
之前在centos7中,默认openssl 1.x版本,对证书验证时(openssl verify)不严格检查 basic Constraints
即使缺少 CA:TRUE 也默认为合法 CA(宽松兼容性)。
 
# 给服务器(域名)颁发证书
# 自己生成私钥和csr,可以自己生成也可以客户端生成
mkdir entain && cd entain
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048
openssl req -new -key server.key -out server.csr
 
# 创建一个SAN文件
[root@docker-server entain]# cat san.conf
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
 
[alt_names]
DNS.1 = x.com
DNS.2 = entain.x.com
IP.1 = 127.0.0.1
 
 
# 用ca的证书给csr颁发证书
openssl x509 -req -in server.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key  -CAcreateserial -out server.crt -days 365 -extfile san.conf
 
 
# 验证证书链
检查 server.crt 是否正确签署:
openssl verify -CAfile ../ca/ca.crt server.crt
如果输出 server.crt: OK,说明证书链正确。
 
windows必须导入 ca.crt 作为受信任的根证书,否则浏览器或系统不会信任服务器证书。
 
 
 
########################################################################################################################################
# 其它补充资料
# 私钥、公钥、证书 三者的关系
为什么 .crt(证书) 不是公钥?
.crt 是完整的证书,里面包含:
公钥(Public Key)
证书信息(如域名、有效期)
CA 的签名(如果是受信任证书)
 
如果用 OpenSSL 查看 .crt 文件,会发现它不只是公钥:
openssl x509 -in server.crt -text -noout
其中会显示 证书颁发机构(Issuer)、有效期、使用限制 等。
 
openssl x509 -in server.crt -pubkey -noout > server.pub
这样 server.pub 才是单纯的公钥。
 
 
# nginx 加载证书重启报错
SSL: error:0A00018F:SSL routines::ee key too small 表示 SSL/TLS 连接失败。
可能的原因是私钥长度过短,现代 SSL/TLS 需要 至少 2048 位 的 RSA 私钥。
之前没加长度参数,默认是1024
 
# 查看私钥长度
openssl rsa -in server.key -text -noout | grep "Private-Key"
 
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048   # 后面加上长度,默认1024
genpkey         生成私钥(支持多种算法,包括 RSA、ECDSA、Ed25519)。
-algorithm RSA  指定密钥算法为 RSA。
-out server.key 生成的私钥存储在 server.key 文件中。
-pkeyopt rsa_keygen_bits:2048  指定 RSA 密钥长度为 2048 位。
 
 
# 关于 SAN (Subject Alternative Name) 主题备用名称。
它是 X.509 证书扩展字段,用于指定多个域名或IP 地址,使证书能适用于多个网站或服务器。例如:
example.com
www.example.com
sub.example.com
192.168.1.100
 
如果颁发证书时没有配置SAN信息,Chrome 和 Firefox 会报“证书无效”,哪怕 CN 是正确的。
尤其是在 2020 年后所有现代浏览器都不再信任仅带 CN 的证书。
 
chrome提示:
此服务器无法证实它就是 x.x.com - 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。
 
# 查看证书中的SAN信息
openssl x509 -in server.crt -noout -text
可以看到关于SAN字段的信息
略···
X509v3 Subject Alternative Name:
    DNS:x.com, DNS:entain.x.com, IP Address:127.0.0.1
略···
 
通过openssl命令查看了一个Let's Encrypt颁发的证书,其中此字段的值和CN字段值一致。
在实际应用中,直接保持两者一致即可,当然SAN中可以写多个(也就是云平台中卖的 多域名证书)。
 
# 2025-07-10补充
如果有一个证书链证书 fullchain.pem 使用下面命令查看证书信息会不完整
openssl x509 -in fullchain.pem -noout -text
是因为 openssl x509 只能处理一个证书,它不会自动解析同一个文件中的多个证书。
想看完整的需要用下面方式(或者拆分证书链为多个文件单独查看)
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout -text
才能用一条命令查看完整证书链里的信息。

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/5556.html

作者:Venus

服务器运维与性能优化

评论已关闭。