使用 OpenSSL 构建 X.509 三级证书体系
创建 RootCA 根证书
0. 根证书的参数说明
我们将参考 DigiCert_Global_Root_CA 证书, 构建我们自己的 RootCA 证书
DigiCert_Global_Root_CA 证书的证书信息如下:
# 在 Debian 系统中, DigiCert Global Root CA 证书保存在 /usr/share/ca-certificates/mozilla/ 目录下
# openssl x509 -noout -text -in /usr/share/ca-certificates/mozilla/DigiCert_Global_Root_CA.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Validity
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
X509v3 Authority Key Identifier:
03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
Signature Algorithm: sha1WithRSAEncryption
Signature Value:
...
根据 DigiCert_Global_Root_CA.crt 证书作为参考, 假设我们根证书的属性如下:
- 根证书名 MyTrust_Cert_Authority_RSA_Root_CA
- Signature Algorithm: sha256WithRSA ,由于 SHA-1 已弃用, 因此改用 SHA-2。
- Self-signed (DV, OV, EV) 根证书都是自签名的
- Validity: 20 ~ 30 years 有效期都在 20 ~ 30 年左右 (7200 - 10800 天)
- SubjectAltName
- countryName = CN
- organizationName = MyTrust Self-signed Certificacion
- organizationalUnitName = MyTrust Self-signed Root CA
- commonName = MyTrust Certificacion Authority RSA Root CA
- x509v3 extensions 包含的 v3 扩展字段有如下几个:
[v3_ca]- subjectKeyIdentifier = hash
- authorityKeyIdentifier = keyid:always,issuer
- basicConstraints = critical, CA:true
- keyUsage = critical, digitalSignature,keyCertSign, cRLSign
属性说明:
- Root CA 的扩展字段均没有 extendedKeyUsage, subjectAltName, Certificate Authority Information Access, CRL Distribution Points, Certificate Policies 等字段, 而这些字段主要出现在 Intermediate CA 和 User Certificate 中。
- 有的 Root CA basicConstraint 有 pathlen 参数, pathlen 主要是限制 Root CA 下属的 Intermediate CA 的层级数量。如果没有设置 pathlen, 则无限制。如果 pathlen = 0, 说明不能有 Intermediate CA, 只能用于签发用户证书。一般来说, Root CA 的 pathlen 无限制(在 vault 中默认 -1), 而 Intermediate 证书的 pathlen 一般设置为 0 或 1, 证书链不宜太长。
- Root CA 的 Key Usage 通常只有 CRL Sign 和 Certificate Sign, 也就是只用来签发和吊销证书(更确切的说是只用来签发和吊销 Intermediate CA Certificates), 不过也有放宽到 digitalSignature 的
1.创建根证书所需的目录和文件
# 创建一个目录用来保存所有证书和密钥
mkdir -p /PKI_CA/RootCA/
# 创建目录结构。index.txt 和 serial 文件充当平面文件数据库, 以跟踪签名证书。
cd /PKI_CA/RootCA/
mkdir {certs,crl,newcerts,private}
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber
chmod 700 private
2.准备配置文件
创建一个配置文件提供给 OpenSSL 命令创建根证书使用。将根配置文件复制到 /PKI_CA/RootCA/opensslRootCA.cnf
# OpenSSL root CA configuration file.
# Copy to `/PKI_CA/RootCA/opensslRootCA.cnf`.
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /PKI_CA/RootCA
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/MyTrust_Cert_Authority_RSA_Root_CA.pem
certificate = $dir/certs/MyTrust_Cert_Authority_RSA_Root_CA.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/MyTrust_Cert_Authority_RSA_Root_CA.crl
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
emailAddress = Email Address
commonName = Common Name
# Optionally, specify some defaults.
countryName_default = CN
stateOrProvinceName_default =
0.organizationName_default = MyTrust Self-signed Certificacion Authority
organizationalUnitName_default = MyTrust Self-signed Root CA
localityName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical, cRLSign,keyCertSign, digitalSignature
extendedKeyUsage = serverAuth, clientAuth
authorityInfoAccess = OCSP;URI:http://cacerts.mytrust.local/oscp/,caIssuers;URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crt
crlDistributionPoints = URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crl
certificatePolicies = @polsect, 1.2.3.4, 2.23.140.1.1, 2.23.140.1.2.1
[ polsect ]
policyIdentifier = 2.5.29.32.0
CPS.1 = "https://cacerts.mytrust.local/CPS"
userNotice.1 = @notice
[ notice ]
organization = "MyTrust Self-signed Certificacion Authority"
explicitText = "UTF8:Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua"
3.生成 RootCA 根证书私钥
任何拥有根密钥的人都可以颁发受信任的证书, 因此我们将用 AES256 加密算法和 32 位强密码对根密钥进行加密, 来确保创建根密钥 (MyTrust_Cert_Authority_RSA_Root_CA.pem)的安全。
cd /PKI_CA/RootCA/
# 生成 32 位根密钥加密密码
openssl rand -hex 32 > private/rootCA.pass
chmod 400 private/rootCA.pass
# 生成根证书私钥
openssl genrsa -aes256 \
-passout file:private/rootCA.pass \
-out private/MyTrust_Cert_Authority_RSA_Root_CA.pem 4096
# 或者新版本 OpenSSL genpkey命令生成根证书私钥
openssl genpkey -aes256 \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:4096 \
-pass file:private/rootCA.pass \
-out private/MyTrust_Cert_Authority_RSA_Root_CA.pem
# 验证私钥
openssl pkey -in private/MyTrust_Cert_Authority_RSA_Root_CA.pem -passin file:private/rootCA.pass -noout -check
Key is valid
创建私钥的一些说明:
- 创建 RSA 私钥时, 可以同时对其添加密码保护。
- 老版本的 OpenSSL genrsa 命令创建的 RSA 私钥是 PKCS#1 格式的, 不支持 -pbkdf2、-iter 和 -v2prf 选项, 因为这些属性 PKCS#8 格式中的。
- 新版本的 OpenSSL (3.0+) 创建的私钥已经默认是 PKCS#8 格式了。(指定 -aes256 加密算法后, 默认会使用 PBKDF2 函数, 迭代次数为 2048 次, 伪随机算法为 hmacWithSHA256, 并且 key size 默认为 2048 bit)
- 如果不是 PKCS#8 格式, 则建议把私钥转换成 PKCS#8 格式, 使用 openssl pkcs8 命令, 它支持手动指定上述选项。
4.创建根证书
# 切换到工作目录
cd /PKI_CA/RootCA
# 创建自签名根证书
openssl req -config opensslRootCA.cnf \
-key private/MyTrust_Cert_Authority_RSA_Root_CA.pem \
-passin file:private/rootCA.pass \
-new -x509 -days 10800 -sha256 \
-extensions v3_ca \
-out certs/MyTrust_Cert_Authority_RSA_Root_CA.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name []:
Locality Name []:
Organization Name [MyTrust Self-signed Certificacion Authority]:
Organizational Unit Name [MyTrust Self-signed Root CA]:
Email Address []:
Common Name []:MyTrust Cert Authority RSA Root CA
# 可以采用 -subject 参数来指定证书的详细信息, 来简化上诉命令的交互过程
openssl req -config opensslRootCA.cnf \
-subj "/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Root CA" \
-key private/MyTrust_Cert_Authority_RSA_Root_CA.pem \
-passin file:private/rootCA.pass \
-new -x509 -days 10800 -sha256 \
-extensions v3_ca \
-out certs/MyTrust_Cert_Authority_RSA_Root_CA.crt
# 修改根证书访问权限
chmod 444 certs/MyTrust_Cert_Authority_RSA_Root_CA.crt
5.验证 RootCA
cd /PKI_CA/RootCA/
openssl x509 -noout -text -in certs/MyTrust_Cert_Authority_RSA_Root_CA.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
23:3e:4c:e3:24:fd:f9:eb:64:41:0b:21:f8:f7:84:8b:79:bc:4f:5a
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA, CN = MyTrust Cert Authority RSA Root CA
Validity
Not Before: Dec 4 06:10:35 2024 GMT
Not After : Jun 30 06:10:35 2054 GMT
Subject: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA, CN = MyTrust Cert Authority RSA Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
CE:11:F8:D6:07:59:A4:E6:FC:E1:D9:DE:27:E3:92:6F:C7:36:EC:34
X509v3 Authority Key Identifier:
CE:11:F8:D6:07:59:A4:E6:FC:E1:D9:DE:27:E3:92:6F:C7:36:EC:34
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
...
到此我们创建了一个 与 DigiCert_Global_Root_CA.crt 证书基本一致的自签名 RootCA 根证书。
Issuer 和 Subject 相同, 因为证书是自签名的。请注意, 所有根证书都是自签名的
创建 IntermediateCA 中间证书
使用中间证书的目的主要是为了在根证书和服务器证书之间建立链式结构, 因为根证书密钥是在安全的地点离线存储的, 使得根证书不直接参与每个网站的签发, 从而增强了安全性。如果中间证书泄露或受到攻击, 可以通过吊销中间证书来保护整个信任链不受影响。
验证过程: 当浏览器访问一个使用 SSL 的网站时, 它会获取网站的服务器证书(用户证书), 并检查该证书的签发者(CA)。然后浏览器会通过中间证书找到这个 CA 的证书, 并继续往上查找, 直到找到受信任的根证书。如果整个证书链都有效且被信任, 浏览器就会认为该网站是安全的, 并显示安全连接标志。
0. 中间证书属性
我们找到了一个名为 DigiCert TLS RSA SHA256 2020 CA1 的中间证书, 它是由根证书 DigiCert_Global_Root_CA 创建中间证书。
该证书的信息如下:
openssl x509 -in DigiCertTLSRSASHA2562020CA1.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
06:d8:d9:04:d5:58:43:46:f6:8a:2f:a7:54:22:7e:c4
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
Validity
Not Before: Apr 14 00:00:00 2021 GMT
Not After : Apr 13 23:59:59 2031 GMT
Subject: C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Subject Key Identifier:
B7:6B:A2:EA:A8:AA:84:8C:79:EA:B4:DA:0F:98:B2:C5:95:76:B9:F4
X509v3 Authority Key Identifier:
03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertGlobalRootCA.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl
X509v3 Certificate Policies:
Policy: 2.16.840.1.114412.2.1
Policy: 2.23.140.1.1
Policy: 2.23.140.1.2.1
Policy: 2.23.140.1.2.2
Policy: 2.23.140.1.2.3
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
...
查看 DigiCert TLS RSA SHA256 2020 CA1 中间证书的组织结构后, 可以总结中间证书的主要信息如下:
- Issued by Root CA Intermediate CA 证书由 Root CA 签名
- Validity: 3 ~ 10 years 有效期在 3 ~ 10 年左右
- x509 v3 extensions 包含的 v3 扩展字段有如下几个:
- [v3_intermediate_ca]
- subjectKeyIdentifier = hash
- authorityKeyIdentifier = keyid:always,issuer:always
- basicConstraints = critical,CA:true,pathlen:0
- keyUsage = critical, cRLSign,keyCertSign, digitalSignature
- extendedKeyUsage = serverAuth, clientAuth
- authorityInfoAccess = OCSP;URI:http://cacerts.mytrust.local/oscp/,caIssuers;URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crt
- crlDistributionPoints = URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crl
- certificatePolicies = 2.23.140.1.1,2.23.140.1.2.1,2.23.140.1.2.2,2.23.140.1.2.3
- 更多的详细配置参数可以查看
man x509v3_config
- 相比 Root CA, Intermediate CA 的扩展字段增加了 Extended Key Usage、Authority Information Access、CRL Distribution Points、Certificate Policies 等字段, 不过依然没有 subjectAltName 字段。subjectAltName 通常只出现在 User 证书上。除此之外, Intermediate CA 和 User Certificate 的扩展字段基本相同。
- Intermediate CA 证书的 pathlen 一般设置为 0 或 1, 也就是不再下辖下级中间证书或者最多再下辖一个中间证书。
- 另外, Intermediate CA 证书的有效期也要更短, 通常是 3 ~ 10 年。其它部分与 Root CA 没有太大区别。
- pathlen:0 表示只能签发端证书, 不能再有 intermediate CA
中间证书的属性如下:
根据 DigiCert TLS RSA SHA256 2020 CA1 中间证书参考,设定我们自己的中间证书属性如下:
- Intermediata CA 证书起名 (Common Name) 为 MyTrust_Cert_Authority_RSA_Intermediate_ICA1
- Common Name: MyTrust Cert Authority RSA Intermediate ICA1
- Issuer: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA
- 有效期 10 年
- Country Name 和 Organization 与 Root CA 对应的值相同 (Policy match)
- 私钥算法和长度: RSA:4096 (默认 2048)
- 摘要签名算法: SHA256 (默认 SHA256)
- 密钥是否加密: 加密
1. 准备中间目录
创建与根 CA 具有相同目录结构。创建 csr 目录来保存证书签名请求也很方便。
mkdir -p /PKI_CA/IntermediateCA
cd /PKI_CA/IntermediateCA/
mkdir {certs,crl,newcerts,private,csr}
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber
chmod 700 private
将中间配置文件复制到 /PKI_CA/IntermediateCA/opensslICA.cnf 。与根 CA 配置文件相比, 更改了五个选项:
dir private_key certificate crl policy
# OpenSSL intermediate CA configuration file.
# Copy to `/PKI_CA/IntermediateCA/opensslICA.cnf`.
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /PKI_CA/IntermediateCA
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.pem
certificate = $dir/certs/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crl
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose
copy_extensions = copy
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
emailAddress = Email Address
commonName = Common Name
# Optionally, specify some defaults.
countryName_default = CN
stateOrProvinceName_default =
0.organizationName_default = MyTrust Self-signed Certificacion Authority
organizationalUnitName_default = MyTrust Self-signed Root CA
localityName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature,keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
[ client_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
authorityInfoAccess = OCSP;URI:http://ocsp2.example.com
#subjectAltName = @alt_names
#[ alt_names ]
#DNS.1 = example.com
#DNS.2 = www.example.com
#DNS.3 = m.example.com
[ user_cert ]
# Extensions for client certificates ('man x509v3_config').
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth,serverAuth
authorityInfoAccess = OCSP;URI:http://cacerts.mytrust.local/oscp/,caIssuers;URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
crlDistributionPoints = URI:http://cacerts.mytrust.local/crl/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crl
certificatePolicies = @pol
#subjectAltName = @alt_names
[pol]
policyIdentifier = 2.5.29.32.0 #DV
CPS.1 = "https://cacerts.mytrust.local/CPS"
userNotice.1 = @notice
[notice]
explicitText = "UTF8:Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua"
2. 创建中间私钥((Intermediate pem)
创建中间证书密钥 (ca.key.pem), 使用 AES 256 位加密和强密码加密中间证书密钥。
# 生成中间证书私钥密码
cd /PKI_CA/IntermediateCA
openssl rand -hex 32 > private/IntermediateCA.pass
chmod 400 private/IntermediateCA.pass
# 生成中间私钥私钥
openssl genpkey -aes256 \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:4096 \
-pass file:private/IntermediateCA.pass \
-out private/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.pem
chmod 400 private/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.pem
# 验证私钥
openssl rsa -in private/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.pem -passin file:private/IntermediateCA.pass -check -noout
RSA key ok
3. 创建中间证书签名请求 (CSR)
使用中间密钥创建证书签名请求 (Certificate Signing Request)。详细信息通常应与根 CA 匹配,Common Name 必须不同。
# 切换目录
cd /PKI_CA/IntermediateCA/
# 生成 中间证书请求文件 CSR
openssl req -config opensslICA.cnf -new -sha256 \
-key private/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.pem \
-passin file:private/IntermediateCA.pass \
-subj "/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Intermediate ICA1" \
-out csr/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.csr
# 验证 CSR
openssl req -text -noout -in csr/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = CN, O = MyTrust Self-signed Certificacion, OU = MyTrust Self-signed Root CA, CN = MyTrust Certificacion Authority RSA Intermediate CA1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
...
Exponent: 65537 (0x10001)
Attributes:
(none)
Requested Extensions:
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
...
4. 创建中间证书
要创建中间证书, 请使用带有 [v3_intermediate_ca] 扩展的根 CA 对中间 CSR 进行签名。中间证书的有效期应短于根证书。十年是合理的。
# 切换目录
cd /PKI_CA/
# 使用根证书签发中间证书
openssl ca -config RootCA/opensslRootCA.cnf \
-extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-in IntermediateCA/csr/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.csr \
-passin file:RootCA/private/rootCA.pass \
-out IntermediateCA/certs/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
Using configuration from RootCA/opensslRootCA.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4096 (0x1000)
Validity
Not Before: Dec 9 09:19:44 2024 GMT
Not After : Dec 7 09:19:44 2034 GMT
Subject:
countryName = CN
organizationName = MyTrust Self-signed Certificacion Authority
organizationalUnitName = MyTrust Self-signed Root CA
commonName = MyTrust Cert Authority RSA Intermediate ICA1
X509v3 extensions:
X509v3 Subject Key Identifier:
07:96:5A:8B:25:3F:46:23:9F:30:71:DF:0A:FF:26:3E:1E:8F:49:D2
X509v3 Authority Key Identifier:
keyid:CE:11:F8:D6:07:59:A4:E6:FC:E1:D9:DE:27:E3:92:6F:C7:36:EC:34
DirName:/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Root CA
serial:23:3E:4C:E3:24:FD:F9:EB:64:41:0B:21:F8:F7:84:8B:79:BC:4F:5A
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Authority Information Access:
OCSP - URI:http://cacerts.mytrust.local/oscp/
CA Issuers - URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://cacerts.mytrust.local/CPS
User Notice:
Organization: MyTrust Self-signed Certificacion Authority
Number:
Explicit Text: Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua
Policy: 1.2.3.4
Policy: 2.23.140.1.1
Policy: 2.23.140.1.2.1
Certificate is to be certified until Dec 7 09:19:44 2034 GMT (3650 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
Database updated
5. 验证证书
# 切换目录
cd /PKI_CA
# 验证中间证书
openssl x509 -noout -text -in IntermediateCA/certs/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA, CN = MyTrust Cert Authority RSA Root CA
Validity
Not Before: Dec 9 09:19:44 2024 GMT
Not After : Dec 7 09:19:44 2034 GMT
Subject: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA, CN = MyTrust Cert Authority RSA Intermediate ICA1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
07:96:5A:8B:25:3F:46:23:9F:30:71:DF:0A:FF:26:3E:1E:8F:49:D2
X509v3 Authority Key Identifier:
keyid:CE:11:F8:D6:07:59:A4:E6:FC:E1:D9:DE:27:E3:92:6F:C7:36:EC:34
DirName:/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Root CA
serial:23:3E:4C:E3:24:FD:F9:EB:64:41:0B:21:F8:F7:84:8B:79:BC:4F:5A
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Authority Information Access:
OCSP - URI:http://cacerts.mytrust.local/oscp/
CA Issuers - URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Root_CA.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://cacerts.mytrust.local/CPS
User Notice:
Organization: MyTrust Self-signed Certificacion Authority
Number:
Explicit Text: Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua
Policy: 1.2.3.4
Policy: 2.23.140.1.1
Policy: 2.23.140.1.2.1
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
...
# 根据根证书验证中间证书。OK 表示信任链完好无损。
openssl verify -CAfile certs/MyTrust_Cert_Authority_RSA_Root_CA.crt IntermediateCA/certs/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
IntermediateCA/certs/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt: OK
创建 User/Leaf 证书
User 证书处于证书链的最下游, 因此也叫 Leaf 证书。 我们平时接触最多的就是 User 证书, 因为所有的 HTTPS 应用都需要一个合法的 User 证书才能正常工作。
我们将使用 中间 CA 对 User 证书进行签名。您可以在各种情况下使用这些签名证书, 例如保护与 Web 服务器的连接或对连接到服务的客户端进行身份验证。
User 证书格式
User 证书中的 extensions 字段与 Intermediate CA 证书基本相同, 唯一一个区别是 User 证书中有 subjectAltName 字段, 这也是重要的一个字段, 如果你签发的 User 证书没有这个字段, 那么会被认为不是一个合规的证书, 浏览器会拒绝。
User 证书的属性一般有以下几种:
- User 证书的名字 (Common Name) 通常为域名或泛域名。
- 有效期 1 年(短的有 1 到 3 个月, 长的则 1 年左右)
- 证书类型: DV
- Policy ID 为 2.23.140.1.2.1
- DV 类型的证书 Subject 中只需要填写 Common Name。
- Key Usage: Digital Signature, Key Encipherment
- Extended Key Usage: Client Auth, Server Auth
- 私钥算法和长度: RSA:4096 (默认 2048)
- 摘要签名算法: SHA256 (默认 SHA256)
- 密钥是否加密: 否
创建 User 证书请求文件
我们的根证书和中间正式采用的是 4096 位。服务器和客户端证书通常在一年后过期, 因此我们可以安全地使用 2048 位。
尽管 4096 位比 2048 位略安全, 但它会减慢 TLS 握手的速度, 并显著增加握手期间的处理器负载。因此, 大多数网站都使用 2048 位私钥。如果对私钥进行加密, 则每次重新启动 Web 服务器时都需要输入私钥的加密密码, 因此我么在创建 User 证书时不加密私钥
# 创建 User 证书保存目录
mkdir -p /PKI_CA/UserCerts/{certs,private,csr}
cd /PKI_CA/
# 创建 User 证书请求文件和 User 证书私钥
openssl req -config IntermediateCA/opensslICA.cnf \
-new -newkey rsa:2048 -sha256 -noenc \
-keyout UserCerts/private/example.com.pem \
-subj "/CN=*.example.com" \
-addext "subjectAltName = IP:10.112.6.1, IP:127.0.0.1, DNS:example.com, DNS:*.example.com, DNS:www.example.com" \
-out UserCerts/csr/example.com.csr
# 创建 User 证书私钥时候,也可以使用 EC 加密算法
openssl req -config IntermediateCA/opensslICA.cnf \
-new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -sha256 -noenc \
-keyout UserCerts/private/fnos.local.pem \
-subj "/CN=*.fnos.local" \
-addext "subjectAltName = IP:10.112.6.99, DNS:*.fnos.local, DNS:www.fnos.local" \
-out UserCerts/csr/fnos.local.csr
创建 User 证书
# 切换目录
cd /PKI_CA、
# 使用中间 CA 对 CSR 进行签名,并创建 User 证书
openssl ca -config IntermediateCA/opensslICA.cnf \
-extensions user_cert \
-days 375 -notext -md sha256 \
-passin file:IntermediateCA/private/IntermediateCA.pass \
-in UserCerts/csr/example.com.csr \
-out UserCerts/certs/example.com.crt
Using configuration from IntermediateCA/opensslICA.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4097 (0x1001)
Validity
Not Before: Dec 10 01:42:51 2024 GMT
Not After : Dec 20 01:42:51 2025 GMT
Subject:
commonName = *.example.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Server Certificate
X509v3 Subject Key Identifier:
FC:E4:43:FE:AE:8C:4E:97:E0:42:F8:52:8F:CD:93:4B:7F:B7:A1:87
X509v3 Authority Key Identifier:
keyid:07:96:5A:8B:25:3F:46:23:9F:30:71:DF:0A:FF:26:3E:1E:8F:49:D2
DirName:/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Root CA
serial:10:00
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
Authority Information Access:
OCSP - URI:http://cacerts.mytrust.local/oscp/
CA Issuers - URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://cacerts.mytrust.local/crl/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://cacerts.mytrust.local/CPS
User Notice:
Explicit Text: Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua
X509v3 Subject Alternative Name:
IP Address:10.112.6.1, IP Address:127.0.0.1, DNS:example.com, DNS:*.example.com, DNS:www.example.com
Certificate is to be certified until Dec 20 01:42:51 2025 GMT (375 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
Database updated
# index.txt 文件应包含一个新条目。
cat IntermediateCA/index.txt
V 251220014251Z 1001 unknown /CN=*.example.com
验证 User 证书
# openssl x509 -text -noout -in UserCerts/certs/example.com.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4097 (0x1001)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, O = MyTrust Self-signed Certificacion Authority, OU = MyTrust Self-signed Root CA, CN = MyTrust Cert Authority RSA Intermediate ICA1
Validity
Not Before: Dec 10 01:42:51 2024 GMT
Not After : Dec 20 01:42:51 2025 GMT
Subject: CN = *.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Server Certificate
X509v3 Subject Key Identifier:
FC:E4:43:FE:AE:8C:4E:97:E0:42:F8:52:8F:CD:93:4B:7F:B7:A1:87
X509v3 Authority Key Identifier:
keyid:07:96:5A:8B:25:3F:46:23:9F:30:71:DF:0A:FF:26:3E:1E:8F:49:D2
DirName:/C=CN/O=MyTrust Self-signed Certificacion Authority/OU=MyTrust Self-signed Root CA/CN=MyTrust Cert Authority RSA Root CA
serial:10:00
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
Authority Information Access:
OCSP - URI:http://cacerts.mytrust.local/oscp/
CA Issuers - URI:http://cacerts.mytrust.local/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crt
X509v3 CRL Distribution Points:
Full Name:
URI:http://cacerts.mytrust.local/crl/MyTrust_Cert_Authority_RSA_Intermediate_ICA1.crl
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
CPS: https://cacerts.mytrust.local/CPS
User Notice:
Explicit Text: Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://cacerts.mytrust.local/rpa-ua
X509v3 Subject Alternative Name:
IP Address:10.112.6.1, IP Address:127.0.0.1, DNS:example.com, DNS:*.example.com, DNS:www.example.com
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
...
吊销证书
吊销证书
# 吊销 example.com 证书
openssl ca -config IntermediateCA/opensslICA.cnf \
-passin file:IntermediateCA/private/IntermediateCA.pass \
-revoke UserCerts/certs/example.com.cert
# index.txt 中与 example.com 的证书对应的行现在以字符 R 开头。这意味着证书已被吊销。
cat IntermediateCA/index.txt
R 251220013619Z 241210014203Z 1000 unknown /CN=*.example.com
参考:
感谢 CodeAndRoad 、骏马金龙 编写的 OpenSSL 相关文章 ,从中学习到了非常多关于 openssl 基础用法 和 X.509 三级证书体系 知识点。
浙公网安备 33010602011771号