3.1. 使用二级 CA 签发服务端证书
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/book/pki-tutorials/3.1.request-server-certificate/
本章节介绍如何利用 OpenSSL 命令行工具,使用二级 CA 证书签发服务端证书。
生成密钥
可以自行选择 RSA 或者 EC 密钥,但是需要注意密钥长度:
- RSA 2048
- EC 256
此处使用 RSA 作为示例
1MY_CA_L2_DIR=$RSA_CA_R1_DIR # RSA 二级 CA 的根目录
2
3NEW_CERT_DOMAIN=www.your-domain.com
4NEW_SERVER_KEY_PATH=$MY_CA_L2_DIR/private/server-$NEW_CERT_DOMAIN.key.pem
5
6openssl genrsa -rand $MY_CA_L2_DIR/.rand -out $NEW_SERVER_KEY_PATH 2048
7
8# 或者生成带密码保护的 RSA 密钥
9# openssl genrsa -rand $MY_CA_L2_DIR/.rand -aes-256-cfb -out $NEW_SERVER_KEY_PATH 2048
10
11# 或者选择 EC 密钥。
12# openssl ecparam -rand $MY_CA_L2_DIR/.rand -genkey -name prime256v1 -noout -out $NEW_SERVER_KEY_PATH
13
14# 如果要对 EC 密钥加密,则须接着执行如下命令
15# openssl ec -aes-256-cfb -in $NEW_SERVER_KEY_PATH -out $NEW_SERVER_KEY_PATH
生成证书签名申请表文件(xxx.csr.pem)
这里分成两步。
首先,创建一个申请表草稿(xxx.csr.cnf
),这是一个用于描述要申请的证书的详细信息的文本文件。
1NEW_SERVER_CERT_REQ_PATH=$MY_CA_L2_DIR/csr/server-$NEW_CERT_DOMAIN.csr.cnf
2
3cat > $NEW_SERVER_CERT_REQ_PATH << EOL
4[ req ]
5distinguished_name = req_distinguished_name
6string_mask = utf8only
7req_extensions = req_ext
8x509_extensions = v3_req
9
10# SHA-1 is deprecated, so use SHA-2 instead.
11default_md = sha256
12prompt = no
13
14[ req_distinguished_name ]
15# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
16commonName = $NEW_CERT_DOMAIN
17
18[req_ext]
19subjectAltName = @alt_names
20
21[v3_req]
22subjectAltName = @alt_names
23
24[alt_names]
25# IP.1 = 127.0.0.1
26DNS.1 = $NEW_CERT_DOMAIN
27EOL
注意服务端证书不能省略
subjectAltName
,否则浏览器不识别。
然后使用 openssl req
命令,在该申请表里添加你的证书公钥(注意,这里是新证书的密钥,而不是 CA 的密钥),并使用你证书私钥,对该申请表进行签名,从而得到一个新的文件 xxx.csr.pem
,这是一个 BASE64 编码的 DER 文件。
1NEW_SERVER_CERT_CSR_PATH=$MY_CA_L2_DIR/csr/server-$NEW_CERT_DOMAIN.csr.pem
2
3openssl req \
4 -config $NEW_SERVER_CERT_REQ_PATH \
5 -new -sha256 \
6 -key $NEW_SERVER_KEY_PATH \
7 -out $NEW_SERVER_CERT_CSR_PATH
可以通过如下命令查看该文件的详细信息。
1openssl req \
2 -in $NEW_SERVER_CERT_CSR_PATH \
3 -noout \
4 -text
签发证书
到了最关键的一步,这里使用你上面创建的 xxx.csr.pem
文件里的信息,生成一个 x509 证书文件(xxx.cert.pem
),并使用 CA 的私钥对该证书进行签名。
1NEW_SERVER_CERT_PATH=$MY_CA_L2_DIR/issued_certs/server-$NEW_CERT_DOMAIN.cert.pem
2
3openssl ca \
4 -config $MY_CA_L2_DIR/ca.cnf \
5 -extensions server_cert \
6 -days 180 \
7 -notext \
8 -md sha256 \
9 -batch \
10 -in $NEW_SERVER_CERT_CSR_PATH \
11 -out $NEW_SERVER_CERT_PATH
命令说明:
-
选项
-config $MY_CA_L2_DIR/ca.cnf
该参数用于指定 CA 的配置文件,具体参考前文创建 CA 的说明。
-
选项
-batch
表示采用批量自动化模式,从 CA 配置和命令行参数里直接读取信息,而不是命令行手动输入,也不需要手动确认。
-
选项
-md sha256
指定证书签名时使用额散列摘要算法,如果省略,则默认使用 CA 配置文件里的
default_md
指定的算法。 -
选项
-days
表示证书的有效时长(从签发这一刻的系统时间起算)。如果省略,则默认使用 CA 配置文件里的
default_days
指定的时长。如果有需要生成特定时间(如过期的证书,用于某些测试场景),可以将参数
-days 180
替换为-startdate 220101000000Z -enddate 220301000000Z
,其中,-startdate
表示证书有效期开始时间,格式为YYMMDDhhmmssZ
,即年月日时分秒各用2位数表示,尾部的 Z 表示使用 UTC 时区。-enddate
表示证书有效期结束时间,格式同上。
然后可以通过如下命令查看生成证书的详细信息。
1openssl x509 -noout -text -in $NEW_SERVER_CERT_PATH
通过如下命令验证二级 CA 证书是否可以用根 CA 证书验证。
1openssl verify -CAfile $MY_CA_L2_DIR/ca.fullchain.pem $NEW_SERVER_CERT_PATH
生成证书链文件
1NEW_SERVER_FULLCHAIN_PATH=$MY_CA_L2_DIR/issued_certs/server-$NEW_CERT_DOMAIN.fullchain.pem
2
3cat > $NEW_SERVER_FULLCHAIN_PATH << EOL
4$(cat $NEW_SERVER_CERT_PATH)
5
6$(cat $MY_CA_L2_DIR/ca.fullchain.pem)
7EOL
然后用如下命令检查证书链完整性。
1openssl verify -CAfile $MY_CA_L2_DIR/ca.fullchain.pem $NEW_SERVER_FULLCHAIN_PATH
至此,你已经成功生成了一个服务端证书,可以用于配置你的服务端。