可以自行选择 RSA 或者 ECC 密钥,但是需要注意密钥长度:
- RSA 2048
- ECC 256
此处使用 ECC 作为示例
MY_CA_L2_DIR=$ECC_CA_E1_DIR # ECC 二级 CA 的根目录
NEW_CERT_DOMAIN=www.yourdomain.com
NEW_SERVER_KEY_PATH=$MY_CA_L2_DIR/private/server-$NEW_CERT_DOMAIN.key.pem
openssl genrsa -rand $MY_CA_L2_DIR/.rand -out $NEW_SERVER_KEY_PATH 2048
# 或者生成带密码保护的 RSA 密钥
# openssl genrsa -rand $MY_CA_L2_DIR/.rand -aes-256-cfb -out $NEW_SERVER_KEY_PATH 2048
# 或者选择 EC 密钥。
# openssl ecparam -rand $MY_CA_L2_DIR/.rand -genkey -name prime256v1 -noout -out $NEW_SERVER_KEY_PATH
# 如果要对 EC 密钥加密,则须接着执行如下命令
# openssl ec -aes-256-cfb -in $NEW_SERVER_KEY_PATH -out $NEW_SERVER_KEY_PATH
这里分成两步。
首先,创建一个申请表草稿(xxx.csr.cnf
),这是一个用于描述要申请的证书的详细信息的文本文件。
NEW_SERVER_CERT_REQ_PATH=$MY_CA_L2_DIR/csr/server-$NEW_CERT_DOMAIN.csr.cnf
cat > $NEW_SERVER_CERT_REQ_PATH << EOL
[ req ]
distinguished_name = req_distinguished_name
string_mask = utf8only
req_extensions = req_ext
x509_extensions = v3_req
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
prompt = no
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = $NEW_CERT_DOMAIN
[req_ext]
subjectAltName = @alt_names
[v3_req]
subjectAltName = @alt_names
[alt_names]
# IP.1 = 127.0.0.1
DNS.1 = $NEW_CERT_DOMAIN
EOL
注意服务端证书不能省略
subjectAltName
,否则浏览器不识别。
然后使用 openssl req
命令,在该申请表里添加你的证书公钥(注意,这里是新证书的密钥,而不是 CA 的密钥),并使用你证书私钥,对该申请表进行签名,从而得到一个新的文件 xxx.csr.pem
,这是一个 BASE64 编码的 DER 文件。
NEW_SERVER_CERT_CSR_PATH=$MY_CA_L2_DIR/csr/server-$NEW_CERT_DOMAIN.csr.pem
openssl req \
-config $NEW_SERVER_CERT_REQ_PATH \
-new -sha256 \
-key $NEW_SERVER_KEY_PATH \
-out $NEW_SERVER_CERT_CSR_PATH
可以通过如下命令查看该文件的详细信息。
openssl req \
-in $NEW_SERVER_CERT_CSR_PATH \
-noout \
-text
到了最关键的一步,这里使用你上面创建的 xxx.csr.pem
文件里的信息,生成一个 x509 证书文件(xxx.cert.pem
),并使用 CA 的私钥对该证书进行签名。
NEW_SERVER_CERT_PATH=$MY_CA_L2_DIR/newcerts/server-$NEW_CERT_DOMAIN.cert.pem
openssl ca \
-config $MY_CA_L2_DIR/ca.cnf \
-extensions server_cert \
-days 180 \
-notext \
-md sha256 \
-batch \
-in $NEW_SERVER_CERT_CSR_PATH \
-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
表示证书有效期结束时间,格式同上。
然后可以通过如下命令查看生成证书的详细信息。
openssl x509 -noout -text -in $NEW_SERVER_CERT_PATH
通过如下命令验证二级 CA 证书是否可以用根 CA 证书验证。
openssl verify -CAfile $MY_CA_L2_DIR/ca.fullchain.pem $NEW_SERVER_CERT_PATH
NEW_SERVER_FULLCHAIN_PATH=$MY_CA_L2_DIR/newcerts/server-$NEW_CERT_DOMAIN.fullchain.pem
cat > $NEW_SERVER_FULLCHAIN_PATH << EOL
$(cat $NEW_SERVER_CERT_PATH)
$(cat $MY_CA_L2_DIR/ca.fullchain.pem)
EOL
然后用如下命令检查证书链完整性。
openssl verify -CAfile $MY_CA_L2_DIR/ca.fullchain.pem $NEW_SERVER_FULLCHAIN_PATH