OpenSSL与根和中间CA创建证书链
Openssl创建证书链需要根CA和中间证书,在本文中,我将共享分步指南,以创建根证书和中间证书,然后使用这些证书在Linux中创建证书CA捆绑包。
我希望我们对与OpenSSL一起使用的所有术语有所了解。
根vs中级证书
证书链或者证书CA捆绑包是一系列证书,其中链中的每个证书都由后续证书签名。
根CA是证书链的顶层,而中间CA或者子CA是从中间根发出的证书颁发机构。
通常,根CA不会直接签署服务器或者客户端证书。
根CA仅用于创建一个或者多个中间CA,这些CA被根CA信任以代表它们签名证书。
这是最佳做法。由于根密钥的任何破坏都是灾难性的,它允许根密钥保持脱机状态并尽可能地不使用。
中间证书颁发机构(CA)是可以代表根CA签署证书的实体。
根CA签署中间证书,形成信任链。
使用中间CA的目的主要是为了安全性。
根密钥可以保持脱机状态,并尽可能少地使用。
如果中间密钥被泄露,则根CA可以撤销中间证书并创建新的中间密码对。
安装OpenSSL
在RHEL/CentOS 7/8上,我们可以分别使用yum或者dnf;而在Ubuntu上,可以使用" apt-get"安装openssl rpm。
说明:
在RHEL系统上,我们必须具有RHN的有效订阅,或者我们可以配置本地脱机存储库,通过该本地脱机存储库,yum
软件包管理器可以安装提供的rpm及其依赖项。
[root@centos8-1 ~]# yum -y install openssl
使用加密密码的OpenSSL加密数据
当我们为根CA证书创建私钥时,我们可以选择对私钥使用加密,也可以创建不进行任何加密的密钥。
就像我们选择使用3DES,AES这样的加密方式创建私钥一样,每次尝试访问私钥时,我们都必须提供密码。
之前我们介绍过使用盐腌密码对openssl encd数据进行加密的步骤。
因此,将不再其中重复这些步骤。
对于本文中的所有示例,我们将使用相同的加密密码文件,以演示openssl创建证书链示例。
创建OpenSSL根CA目录结构
我们还可以使用所有证书创建CA捆绑包,而无需创建任何目录结构和使用一些手动调整,但是让我们按照漫长的过程来更好地理解。
在RHEL/CentOS 7/8中,所有证书的默认位置都在/etc/pki/tls下。
但是对于本文,我们将创建一个新的目录结构"/root/tls /"来存储我们的证书。
创建一个父目录来存储证书
[root@centos8-1 ~]# mkdir /root/tls [root@centos8-1 ~]# cd /root/tls
在CA的根目录中,我们需要创建两个子目录:
certs:
这将用于保留我们通过CA颁发的所有证书的副本。private:
这将用于保留CA证书的私钥的副本。
重要的提示:
CA所使用的大多数文件对系统上的任何人或者至少使用我们CA所颁发的证书的任何人都是可见的。
一个值得注意的例外是CA证书的私钥。
切勿将私钥透露给未经授权从我们的CA颁发证书或者CRL的任何人。
私钥应该存储在硬件中,或者至少存储在永远不会放在网络上的计算机上
[root@centos8-1 tls]# mkdir certs private
除了密钥生成之外,我们还将创建CA基础结构所需的三个文件。
一个"序列"文件用于"跟踪用于颁发证书的最后一个序列号"。
重要的是,永远不会从同一CA颁发具有相同序列号的两个证书。
OpenSSL如何处理此文件有些古怪。
它期望该值以十六进制表示,并且必须至少包含两位数,因此我们必须在其前面加上一个零以填充该值。
[root@centos8-1 tls]# echo 01 > serial
接下来,我们将创建" index.txt"文件,该文件是一种"数据库",用于跟踪CA颁发的证书。
由于此时尚未颁发证书,并且OpenSSL要求该文件存在,因此我们将简单地创建一个空文件。
[root@centos8-1 tls]# touch index.txt
检查/root/tls
下的内容列表
[root@centos8-1 tls]# ls -l total 32 drwxr-xr-x 2 root root 4096 Apr 8 22:29 certs -rw-r--r-- 1 root root 0 Apr 9 03:36 index.txt -rw-r--r-- 1 root root 32 Apr 8 23:25 mypass.enc drwxr-xr-x 2 root root 4096 Apr 9 03:34 private -rw-r--r-- 1 root root 3 Apr 9 03:37 serial
第4步:为根CA证书配置openssl.cnf
在RHEL/CentOS 7/8中的/etc/pki/tls/openssl.cnf下,我们将有一个默认配置文件" openssl.cnf",由openssl rpm添加。
我们会将文件复制到自定义证书位置,即"/root/tls",并将修改该文件的内容以创建根CA证书
HOME = . RANDFILE = $ENV::HOME/.rnd oid_section = new_oids openssl_conf = default_modules [ default_modules ] ssl_conf = ssl_module [ ssl_module ] system_default = crypto_policy [ crypto_policy ] .include /etc/crypto-policies/back-ends/opensslcnf.config [ new_oids ]
用于CA函数的OpenSSL命令恰当地命名为ca
,因此我们感兴趣的第一部分称为ca
。
就我们的目的而言,本节非常简单,只包含一个键:default_ca。
该值是包含默认CA配置的部分的名称。
" [CA_default]"部分包含一系列默认值。
确保声明我们先前选择的目录/root/tls。
x509_extensions键指定一个部分的名称,该部分将包含要添加到我们的CA颁发的每个证书中的扩展名。
[ ca ] default_ca = CA_default # The default ca section [ CA_default ] dir = /root/tls # Where everything is kept certs = $dir/certs # Where the issued certs are kept database = $dir/index.txt # database index file. # several certs with same subject. new_certs_dir = $dir/certs # default place for new certs. certificate = $dir/certs/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL private_key = $dir/private/cakey.pem # The private key name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha256 # use SHA-256 by default preserve = no # keep passed DN ordering policy = policy_match
policy键指定将用于默认策略的部分的名称。
策略定义是一组与证书可分辨名称中的字段同名的密钥。
对于每个键或者字段,都有三个合法值:"匹配","提供"或者"可选"。
" match:"表示证书请求中具有该名称的字段必须与CA证书中的相同字段匹配。
supplied:
表示证书请求必须包含该字段。optional:
表示证书请求中不需要该字段。
我们将应用policy_match
来创建根CA证书,因此我们将其添加为CA_default
下的policy
的默认值。
[ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional
和policy_anything
用于创建中间CA证书
[ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional
创建证书签名请求(CSR)或者证书时,将应用req部分下的值。
x509_extensions键指定包含我们要包含在证书中的扩展名的部分的名称。
[ req ] default_bits = 4096 default_md = sha256 default_keyfile = privkey.pem distinguished_name = req_distinguished_name x509_extensions = v3_ca string_mask = nombstr
" eq_distinguished_name"密钥确定OpenSSL如何获取填写证书的专有名称所需的信息。
我提供的默认值很少,而必须提供公共名称,如我们在policy
键下定义的一样。
[ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = IN countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) localityName_default = BANGALORE 0.organizationName = Organization Name (eg, company) 0.organizationName_default = theitroad organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, your name or your server\'s hostname) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64
这些是我们将与openssl创建证书链一起使用的扩展。
我们将使用v3_ca
扩展名来创建根CA证书,并使用v3_intermediate
扩展名来中级CA证书。
[ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true [ v3_intermediate_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign
生成根CA私钥
我们将使用4096位和3DES加密创建根CA密钥
我正在使用加密的密码文件来提供私钥的密码
我们将这个私钥存储在
/root/tls/private
下。
[root@centos8-1 tls]# openssl genrsa -des3 -passout file:mypass.enc -out private/cakey.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes) .......................................................................++++ .......................++++ e is 65537 (0x010001)
重要的提示:
如果此密钥被盗用,则CA的完整性将受到损害,这实质上意味着,无论颁发的证书是在密钥被盗用之前还是之后,都将不再受信任。
OpenSSL验证根CA密钥
我们将使用openssl命令查看私钥的内容:
[root@centos8-1 tls]# openssl rsa -noout -text -in private/cakey.pem -passin file:mypass.enc RSA Private-Key: (4096 bit, 2 primes) <Output trimmed>
创建自己的根CA证书
OpenSSL创建证书链需要根证书和中间证书。
在此步骤中,我们将替换VeriSign,Thawte等。使用根CA密钥
cakey.pem
创建根CA证书cacert.pem
。给予根证书有效期较长。
一旦根证书过期,则由CA签名的所有证书都将失效。每当使用" openssl req"工具时,都必须指定要与" -config"方法一起使用的配置文件,否则OpenSSL将默认为" /etc/pki/tls/openssl.cnf"
我们将使用
v3_ca
扩展名来创建CA证书
重要的提示:
" CA和服务器证书的通用名称(CN)不能匹配",否则将发生命名冲突,稍后我们将收到错误消息。
使用以下命令创建根证书颁发机构证书cacert.pem
[root@centos8-1 tls]# openssl req -new -x509 -days 3650 -passin file:mypass.enc -config openssl.cnf -extensions v3_ca -key private/cakey.pem -out certs/cacert.pem 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) [IN]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) [BANGALORE]: Organization Name (eg, company) [theitroad]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:centos8-1 Email Address []:[email protected]
将证书的格式更改为PEM格式
[root@centos8-1 tls]# openssl x509 -in certs/cacert.pem -out certs/cacert.pem -outform PEM
OpenSSL验证证书
对openssl执行以下命令以验证根CA证书
[root@centos8-1 tls]# openssl x509 -noout -text -in certs/cacert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 55:b2:c2:5e:7b:95:4a:05:78:32:82:6f:b1:60:a0:92:03:96:0b:30 Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = Some-State, L = BANGALORE, O = theitroad, CN = centos8-1, emailAddress = [email protected] Validity Not Before: Apr 11 11:34:22 2017 GMT Not After : Apr 9 11:34:22 2030 GMT Subject: C = IN, ST = Some-State, L = BANGALORE, O = theitroad, CN = centos8-1, emailAddress = [email protected] Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) <Output trimmed>
输出显示:
使用的"签名算法"
证书有效期的"日期"
"公钥"位的长度
"签发者",即签署证书的实体
"主题",指的是证书本身
说明:
由于证书是自签名的,因此颁发者和主题是相同的。
输出还显示X509v3扩展。
我们应用了v3_ca
扩展名,因此[[v3_ca]`中的选项应反映在输出中。
X509v3 extensions: X509v3 Subject Key Identifier: 0B:FE:44:49:A9:90:96:9A:19:17:56:55:2D:70:B0:0D:D8:5D:9A:73 X509v3 Authority Key Identifier: keyid:0B:FE:44:49:A9:90:96:9A:19:17:56:55:2D:70:B0:0D:D8:5D:9A:73 X509v3 Basic Constraints: critical CA:TRUE
创建OpenSSL中级CA目录结构
现在,要完成openssl create证书链的设置,我们还将需要CA捆绑包的中间证书。
我们将在父文件夹"/root/tls"下创建新的目录结构"/root/tls/intermediate",以将两个证书文件分开。
[root@centos8-1 tls]# mkdir /root/tls/intermediate [root@centos8-1 tls]# cd /root/tls/intermediate
我们还将在/root/tls/intermediate下创建子目录,以存储我们的密钥和证书文件。
我们还需要为根CA证书创建的" serial"和" index.txt"文件。
[root@centos8-1 intermediate]# mkdir certs csr private [root@centos8-1 intermediate]# touch index.txt [root@centos8-1 intermediate]# echo 01 > serial
在中间CA目录树中添加一个" crlnumber"文件。
crlnumber用于跟踪证书吊销列表。
[root@centos8-1 intermediate]# echo 01 > /root/tls/intermediate/crlnumber
为中级CA证书配置openssl.cnf
将用于我们的根CA证书的" openssl.cnf"从" /root/tls/openssl.cnf"复制到" /root/tls/intermediate/openssl.cnf"。
与根CA证书配置文件相比,以下是我们已更改的选项:
dir = /root/tls/intermediate # Where everything is kept certificate = $dir/certs/intermediate.cacert.pem # The CA certificate private_key = $dir/private/intermediate.cakey.pem # The private key policy = policy_anything
步骤9:生成中间CA密钥
使用具有3DES加密的openssl genrsa和我们的加密密码短语文件生成中间CA密钥" ca-intermediate.key",以避免出现任何密码提示。
[root@centos8-1 tls]# openssl genrsa -des3 -passout file:mypass.enc -out intermediate/private/intermediate.cakey.pem 4096 Generating RSA private key, 4096 bit long modulus (2 primes) ...........................................................................++++ ............................................................................++++ e is 65537 (0x010001)
0:创建立即CA证书签名请求(CSR)
使用中间CA密钥创建证书签名请求(CSR)。
详细信息通常应与根CA相匹配。
"但是,通用名称必须不同。
"
接下来,我们将在/root/tls/intermediate/csr
下创建中间CA证书签名请求(CSR),其到期值小于根CA证书
[root@centos8-1 tls]# openssl req -new -sha256 -config intermediate/openssl.cnf -passin file:mypass.enc -key intermediate/private/intermediate.cakey.pem -out intermediate/csr/intermediate.csr.pem 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) [IN]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) [BANGALORE]: Organization Name (eg, company) [theitroad]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:centos8-1 Intermediate CA Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
1:签名并生成立即CA证书
现在,在结束openssl创建证书链之前的最后一步,我们需要使用在上一步中创建的证书签名请求创建立即CA证书。
我们将使用/root/tls/openssl.cnf
中的v3_intermediate_ca
扩展名在/root/tls/intermediate/certs/intermediate.cacert.pem
下创建中间CA证书。
[root@centos8-1 tls]# openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 2650 -notext -batch -passin file:mypass.enc -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cacert.pem Using configuration from openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Apr 9 13:40:23 2017 GMT Not After : May 12 13:40:23 2027 GMT Subject: countryName = IN stateOrProvinceName = Some-State organizationName = theitroad commonName = centos8-1 Intermediate CA emailAddress = [email protected] X509v3 extensions: X509v3 Subject Key Identifier: A4:07:28:66:F1:71:CD:0B:62:2E:01:8C:6B:04:5B:CC:D0:96:24:89 X509v3 Authority Key Identifier: keyid:0B:FE:44:49:A9:90:96:9A:19:17:56:55:2D:70:B0:0D:D8:5D:9A:73 X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Key Usage: critical Digital Signature, Certificate Sign, CRL Sign Certificate is to be certified until May 12 13:40:23 2027 GMT (2650 days) Write out database with 1 new entries Data Base Updated
" index.txt"文件是OpenSSL ca工具存储证书数据库的位置。
请勿手动删除或者编辑此文件。
"它现在应该包含引用中间证书的行。
"
[root@centos8-1 tls]# cat index.txt V 270712134023Z 01 unknown /C=IN/ST=Some-State/O=theitroad/CN=centos8-1 Intermediate CA/[email protected]
OpenSSL验证证书
验证中间CA证书内容
[root@centos8-1 tls]# openssl x509 -noout -text -in intermediate/certs/intermediate.cacert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha256WithRSAEncryption Issuer: C = IN, ST = Some-State, L = BANGALORE, O = theitroad, CN = centos8-1, emailAddress = [email protected] Validity Not Before: Apr 9 13:40:23 2017 GMT Not After : May 12 13:40:23 2027 GMT Subject: C = IN, ST = Some-State, O = theitroad, CN = centos8-1 Intermediate CA, emailAddress = [email protected] Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit)
接下来,openssl根据根证书验证中间证书。
OK(确定)表示信任链完整无缺。
[root@centos8-1 tls]# openssl verify -CAfile certs/cacert.pem intermediate/certs/intermediate.cacert.pem intermediate/certs/intermediate.cacert.pem: OK
将证书的格式转换为PEM格式
[root@centos8-1 tls]# openssl x509 -in intermediate/certs/intermediate.cacert.pem -out intermediate/certs/intermediate.cacert.pem -outform PEM
2:OpenSSL创建证书链(证书捆绑包)
要打开openssl创建证书链(证书捆绑包),请将中间证书和根证书连接在一起。
在下面的示例中,我将Linux中的根CA证书和中级CA证书组合到openssl创建证书链中。
我们稍后将使用此文件来验证由中间CA签名的证书。
[root@centos8-1 tls]# cat intermediate/certs/intermediate.cacert.pem certs/cacert.pem > intermediate/certs/ca-chain-bundle.cert.pem
OpenSSL验证证书链
openssl创建证书链后,使用以下命令来验证证书链:
[root@centos8-1 tls]# openssl verify -CAfile certs/cacert.pem intermediate/certs/ca-chain-bundle.cert.pem intermediate/certs/ca-chain-bundle.cert.pem: OK
要验证在线页面(例如Google)的证书链,请执行以下操作:
[root@centos8-1 certs]# openssl s_client -quiet -connect google.com:443 depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1 depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com verify return:1
要显示来自Google证书链的证书,请执行以下操作:
[root@centos8-1 certs]# openssl s_client -showcerts -connect google.com:443 CONNECTED(00000003) depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1 depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com verify return:1 <Output trimmed>