搭建私有CA,并用私有CA实现证书签发。那么就需要了解证书的一些基础术语。
在上一篇博客中已经介绍过对称加密和非对称加密,详见2. TLS密钥交换过程部分的介绍。
非对称加密解决的是通信双方无需交换共有密钥(对称加密的时候,加密和解密双方使用的是相同的密码,所以加密一方将数据发送给另一方之后,另一方需要拥有相同的密码才能解开并抽取加密的内容,即共有密钥)的前提下实现安全通信,而这是通过双方互换公钥实现的。每一方都有自己的公私密钥对,使用公钥加密的数据,需要使用与公钥对应的私钥才能解密。A,B双方建立通信的时候,会互换公钥,A使用B的公钥将数据加密之后发送给B,B接收到A发送过来的加密内容之后,使用B的私钥将加密的内容解密。同理,B使用A的公钥将数据加密之后发送给A,A接收到B发送过来的数据之后,使用A的私钥将加密数据解密。
公私密钥对除了可以实现数据加密之外,还可以用于签名以及验证签名。使用私钥进行签名,然后使用公钥对私钥的签名进行验证,如果验证通过,说明是一对公司密钥。
如果在通信双方还未建立互信的时候,是如何完成公钥互换的呢?此时通过发送公钥给对方,然后让对方使用公钥加密之后,将数据返回,正常解密之后,即说明这个公私密钥对是匹配的。比如A要与B通信,B将自己的公钥发送给A,告诉A用这个公钥加密数据与B进行通信。而这个过程,需要借助PKI(Public Key Infrastructure,即公钥基础架构)来实现。
PKI是通过CA(Certificate Authority,即证书权威)实现的绑定公钥协议,CA是其公钥已经预知的集中化受信的第三方。通过CA的方式,当A与B通信的时候,B会给A发送一个经过C签署的证书文件,而A是知道C并且信任C的,并且告诉A这个是B的公钥。这个被签发的信息就是证书,其中也会包含一些其他的信息,A是可以验证C签发的证书的,因为A事先已经有了C的公钥,所以此时可以通过这个证书与B建立互信的通信过程。
C为什么可信呢?因为C被根CA - D签署了证书,而互联网上的每个主机都知道D,而D在给C签发证书的时候,在其中包含了证书链文件,即证明C是由D签发的,是可信的。所以当A与B通信的时候,B将C签发的证书和证书链文件发给A,A通过证书链文件验证证书可信,之后建立正常通信过程。
x509演化到现在,分为3个版本:
x509v3版本的数字证书中,包含如下内容:
其中,Issuer签发者和Subject证书主体包含的内容如下:
比如C=CN, ST=Beijing, L=beijing, O=Example Ltd, OU=IT, CN=www.example.com
另外一个重要的部分就是证书主体的公钥信息,其中包括如下内容:
清楚了上述的这些基本术语,接下来就可以着手搭建私有CA,并给服务器签发证书了。实际的CA中,通常分为根CA和中间CA(也叫代理CA),根CA只负责给中间CA签发证书,不对互联网上的其他主机进行证书签发操作,这样可以确保根CA的私钥安全性,如果某个中间CA不安全了,那么只需要在根CA上将其证书吊销即可,那么所有由这个中间CA签发的服务器证书就全部不可信了。中间CA则是面对最终服务器进行证书签发处理。
为了模拟这个架构,我们将会使用3台虚拟机来完成本实验:c7u6s1用作根CA,c7u6s2用于中间CA(Intermediate CA),c7u6s3用作发起证书签属请求的服务器。
构建私有CA需要频繁使用到openssl
这个命令。在开始构建之前,先简单介绍下这个命令。
这个命令支持两种操作模式:交互式和非交互式,下面的操作中,将在非交互模式完成。
其支持三种子命令形式:
ca, crl, genrsa, req, verify, x509
等命令sha256, sha512
等命令base64, des3, aes256
等命令要查看某个子命令的具体用法,在命令行中执行如下命令即可:
[root@LiuXianQiE ~]# openssl rsa --help Usage: rsa [options] Valid options are: -help Display this summary -inform format Input format, one of DER PEM -outform format Output format, one of DER PEM PVK -in val Input file -out outfile Output file -pubin Expect a public key in input file -pubout Output a public key -passout val Output file pass phrase source -passin val Input file pass phrase source -RSAPublicKey_in Input is an RSAPublicKey -RSAPublicKey_out Output is an RSAPublicKey -noout Don't print key out -text Print the key in text -modulus Print the RSA key modulus -check Verify key consistency -* Any supported cipher -pvk-strong Enable 'Strong' PVK encoding level (default) -pvk-weak Enable 'Weak' PVK encoding level -pvk-none Don't enforce PVK encoding -engine val Use engine, possibly a hardware device [root@LiuXianQiE ~]#
上述即列出了openssl rsa
这个子命令所支持的具体选项和含义。
创建根CA需要用到加密的私钥和可公开的证书,即证书密钥对。根密钥文件 ca.key.pem 和 根证书文件 ca.cert.pem。
根CA通常不会直接对服务器进行证书签署,它负责对可信的中间CA(Intermediate CA)进行证书签署,这样即便根CA离线也没有大问题,也可以最大限度的确保根CA安全。
由于用到PKI体系,系统将相关的文件都放在/etc/pki/
这个目录中,包括我们这里作为CA角色的相关配置文件,在/etc/pki/CA/
这个目录下面。
根CA的角色定义,在名为openssl.cnf的配置文件中,其中包含了私钥文件的存放路径等信息。另外为了签署中间CA的证书,还需要一个index.txt的文件(用于记录已经签署的证书和后期吊销的证书信息)以及一个serial文件(记录证书序列号)。将这些文件都放置在/etc/pki/CA/
这个目录中,具体如下所示:
[root@c7u6s1 ~]# cd /etc/pki/CA/ [root@c7u6s1 CA]# touch index.txt [root@c7u6s1 CA]# echo 10 > serial [root@c7u6s1 CA]# vim openssl.cnf [root@c7u6s1 CA]# ls -lFh total 24K drwxr-xr-x. 2 root root 54 Jun 20 16:45 certs/ drwxr-xr-x. 2 root root 6 Oct 31 2018 crl/ -rw-r--r-- 1 root root 99 Jun 20 16:45 index.txt drwxr-xr-x. 2 root root 20 Jun 20 16:45 newcerts/ -rw-r--r-- 1 root root 4.2K Jun 20 16:44 openssl.cnf drwx------. 2 root root 24 Jun 20 16:21 private/ -rw-r--r-- 1 root root 3 Jun 20 16:45 serial [root@c7u6s1 CA]#
openssl.cnf这个配置文件的内容如下所示:
# OpenSSL root CA configuration file. # Copy to `/root/ca/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /etc/pki/CA 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/ca.key.pem certificate = $dir/certs/ca.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/ca.crl.pem 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 = match 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 commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = CN stateOrProvinceName_default = Beijing localityName_default = 0.organizationName_default = LiuXianQiE Intermediate Ltd organizationalUnitName_default = Intermediate CA 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 basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_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, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
上述配置文件中,定义了私钥的位置、证书的存放路径以及吊销列表的相关设置等信息。同时包含了证书主体的一些默认设置。
有了上述这些文件,就可以准备根CA的私钥文件了。具体如下所示:
[root@c7u6s1 CA]# openssl genrsa -aes256 -out private/ca.key.pem 4096 Generating RSA private key, 4096 bit long modulus .................................................................................................++ ......................................................................................................................++ e is 65537 (0x10001) Enter pass phrase for private/ca.key.pem: Verifying - Enter pass phrase for private/ca.key.pem: [root@c7u6s1 CA]# ls certs/ crl/ newcerts/ private/ [root@c7u6s1 CA]# ls private/ ca.key.pem [root@c7u6s1 CA]# ls -lh private/ total 4.0K -rw-r--r-- 1 root root 3.3K Jun 20 16:21 ca.key.pem
上述证书签发时使用的对称密钥长度位4096,实际上,互联网证书通常采用2048位长度进行加密。
openssl的配置文件和私钥文件准备好之后,就可以用这两个文件生成对应的证书文件了。具体如下所示:
[root@c7u6s1 ca]# openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 365 -sha256 -out certs/ca.cert.pem Enter pass phrase for private/ca.key.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) [CN]: State or Province Name [Beijing]: Locality Name []:beijing Organization Name [LiuXianQiE ltd]: Organizational Unit Name []:Linux ^H Common Name []:LiuXianQiE ltd Root CA Email Address []:liuxianqie@localhost.com [root@c7u6s1 ca]#
当执行openssl req
命令的时候,需要通过命令-config openssl.cnf
指定所用的配置文件,如果不指定,那么这条命令执行的时候,将会使用默认的配置文件/etc/pki/tls/openssl.cnf
。
验证根证书可以查看其中的证书信息,比如证书签发者、证书主体、签名算法等。具体如下所示:
[root@c7u6s1 CA]# openssl x509 -noout -text -in certs/ca.cert.pem Certificate: Data: Version: 3 (0x2) Serial Number: db:b6:c9:15:ad:0e:4e:a7 Signature Algorithm: sha256WithRSAEncryption Issuer: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA Validity Not Before: Jun 20 08:23:50 2021 GMT Not After : Jun 20 08:23:50 2022 GMT Subject: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:e5:f3:e9:02:db:13:9e:5b:de:5d:7e:c4:c0:16: 56:21:9e:ab:d3:c1:b1:49:d4:61:c6:b2:40:5e:eb: 0a:5e:2a:ad:d5:92:3b:80:99:03:4b:6f:f7:fb:b0: 00:af:e1:fc:60:fa:81:9b:45:97:31:4a:c8:f0:b5: a3:21:8a:74:6e:f7:6f:ba:0c:29:60:4a:e4:66:e3: f4:39:66:65:2a:6f:c9:d1:d6:93:41:5d:73:fe:4d: 0b:3c:53:87:c8:4c:86:61:87:a1:88:69:c3:19:16: e5:43:3a:e5:a0:72:c8:23:fa:a2:e6:aa:48:df:f3: 47:98:32:49:b2:01:b6:90:ec:85:b6:c0:d3:4a:39: 44:b7:c9:08:7f:91:95:8e:59:82:d6:65:c0:46:a5: 7e:51:71:92:f3:46:98:53:b9:18:67:4c:39:e8:2c: c8:bb:a9:b8:a1:ce:03:be:8b:d2:91:90:65:11:5e: 04:96:1e:86:37:5d:62:4f:f5:93:8e:07:56:8a:53: 83:3d:73:78:84:cc:b9:fc:66:6e:14:c7:86:1b:1f: fc:40:05:35:27:3d:5d:f4:58:4e:09:35:85:33:90: a6:0c:aa:9c:68:a9:4b:2f:23:70:a4:ac:54:30:8f: 44:2f:46:47:76:51:d8:d8:88:2c:5a:aa:a4:96:b6: 94:23:9d:d8:2c:24:cc:6f:7b:72:48:d0:f2:b7:fd: 01:fe:6f:76:cb:b3:52:49:7d:fc:b7:76:32:c2:ab: 9d:1e:2b:a6:e7:dc:a0:e0:59:84:49:98:22:ef:a0: 52:f5:24:d2:90:c2:92:7b:48:d4:ff:98:f5:7c:42: fb:8a:0b:94:b1:2d:3b:79:6c:8f:14:fa:02:00:12: 4e:66:6d:31:e8:fa:e5:0a:e6:7c:30:a1:ff:9c:c1: 8c:5a:9a:77:1d:5c:1d:9c:91:53:1d:85:40:3f:46: c5:21:e1:c1:22:8e:a9:60:32:23:31:c1:74:8d:9a: 07:73:cf Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 0F:93:C4:54:6A:9F:8D:0F:2E:C3:A0:9B:BB:8F:ED:81:43:ED:64:B8 X509v3 Authority Key Identifier: keyid:0F:93:C4:54:6A:9F:8D:0F:2E:C3:A0:9B:BB:8F:ED:81:43:ED:64:B8 X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Digital Signature, Certificate Sign, CRL Sign Signature Algorithm: sha256WithRSAEncryption 1a:c7:a1:3d:d5:cf:23:c7:30:a9:b0:7f:69:ea:72:20:93:b8: 7e:f0:11:9d:81:e4:74:a1:cf:98:2d:36:a0:df:76:bd:9b:56: 66:68:5e:00:aa:fc:34:2b:d3:84:17:68:a8:5e:8f:45:bd:2a: 3b:fd:03:60:b2:85:e3:c2:eb:04:6c:0e:53:5a:c9:bb:49:46: 17:f8:fb:8d:0d:9b:5d:a0:82:12:b5:75:55:41:5b:8d:90:88: b8:d9:9c:1d:f4:0e:3b:fa:e0:55:b3:22:63:0d:88:c0:ab:e8: ea:15:de:d5:83:6a:46:48:5a:99:7e:e9:34:a4:06:cd:af:0b: ec:5a:f8:23:f8:cb:80:a2:56:af:43:5d:9f:71:53:4c:d9:af: 8f:1a:e2:8b:b1:f6:92:83:ce:87:00:dc:bb:1f:a1:75:fd:4a: cf:14:7b:dc:de:6b:e7:f1:43:d6:d4:a4:45:07:f6:d9:a5:d2: 00:4b:55:34:d6:30:b0:5d:0d:45:3d:96:52:cd:78:50:b7:12: ce:4b:f8:f6:cd:be:7f:86:06:1b:cd:6f:0c:40:fa:ee:ce:d9: d4:f4:e4:c6:8f:41:be:92:da:67:dc:52:42:de:0a:bc:20:d0: 07:f3:b1:69:7a:97:e1:58:eb:ec:97:4c:11:4e:23:9e:5b:3b: 3a:a8:39:4c:38:97:fa:63:1a:ee:95:1a:72:d9:36:a1:30:dc: d5:9c:8b:96:ad:fa:9e:8e:7b:6d:55:72:a4:84:6b:bb:2e:f9: 30:40:43:e3:43:f0:02:1b:25:d2:92:97:7c:50:9e:4b:dd:87: 4e:de:d2:f1:93:15:4a:11:d3:ca:5a:6d:70:bf:a9:db:62:12: 44:d8:a1:95:0e:9f:0b:1f:91:9f:f2:90:7c:44:93:24:c1:72: 27:d0:5c:69:cf:cd:e7:3e:64:c9:d5:aa:3e:b8:5a:2c:b8:19: 19:9e:f8:ad:38:64:d5:20:2d:64:15:88:82:e2:e7:58:6f:42: c9:38:26:8b:8e:59:e2:c1:8f:6d:bb:d5:47:4d:59:15:c3:70: ae:33:d3:27:aa:71:3a:9f:5e:76:4f:fd:ab:d4:b3:78:4e:19: 49:44:18:af:30:b1:47:74:a4:34:96:36:64:0c:c4:87:fa:e7: e6:af:be:c0:9d:00:a1:e2:ec:5d:d7:bd:3e:61:b0:41:68:13: 0f:1d:8f:e0:d6:bf:96:6a:be:68:2f:02:f1:ae:e7:e7:83:92: 1f:3b:75:7d:55:85:1a:f5:b9:55:8e:57:48:e5:c0:63:54:9c: 96:d0:aa:43:fb:1e:cf:f7:10:99:af:dd:d5:b2:a0:56:cb:3a: a7:54:90:2e:5b:ba:f1:8b [root@c7u6s1 CA]# [root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -issuer issuer= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -subject subject= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# openssl x509 -in certs/ca.cert.pem -noout -dates notBefore=Jun 20 08:23:50 2021 GMT notAfter=Jun 20 08:23:50 2022 GMT [root@c7u6s1 CA]#
中间CA代表根CA形式对终端服务器的证书签署操作,根CA只负责签署中间CA,从而形成信任的证书链。使用中间CA的目的,主要还是出于安全的目的隔离风险。
中间CA的虚拟机为c7u6s2,准备相应的文件和目录,具体如下所示:
[root@c7u6s2 ~]# cd /etc/pki/CA/ [root@c7u6s2 ~]# vim openssl.cnf [root@c7u6s2 ~]# mkdir csr [root@c7u6s2 CA]# ls certs crl csr newcerts openssl.cnf private
csr是证书签署请求目录,用于存放后面生成的证书签发请求文件。
配置文件openssl.cnf的内容具体如下所示:
# OpenSSL intermediate CA configuration file. # Copy to `/root/ca/intermediate/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /etc/pki/CA certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcertsdatabase = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = $dir/private/intermediate.key.pem certificate = $dir/certs/intermediate.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/intermediate.crl.pem 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 [ policy_strict ] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. countryName = match stateOrProvinceName = match 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 commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = CN stateOrProvinceName_default = Beijing localityName_default = 0.organizationName_default = LiuXianQiE Ltd organizationalUnitName_default = Root CA 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 basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_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, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
同根CA的配置文件类似,其中也指定了私钥的存放路径和位置,证书吊销列表等信息。
使用openssl genrsa -sha256
生成私钥文件,具体如下所示:
[root@c7u6s2 CA]# openssl genrsa -aes256 -out private/intermediate.key.pem 4096 Generating RSA private key, 4096 bit long modulus ...................................................................++ ................++ e is 65537 (0x10001) Enter pass phrase for private/intermediate.key.pem: Verifying - Enter pass phrase for private/intermediate.key.pem: [root@c7u6s2 CA]# chmod 400 private/intermediate.key.pem [root@c7u6s2 CA]# ll -hh private/intermediate.key.pem -r-------- 1 root root 3.3K Jun 20 16:30 private/intermediate.key.pem
生成的私钥文件如下所示:
[root@c7u6s2 CA]# ls private/ -lh total 4.0K -rw-r--r-- 1 root root 3.3K Nov 12 03:50 intermediate.key.pem [root@c7u6s2 CA]# chmod 0400 private/intermediate.key.pem [root@c7u6s2 CA]# ls -lhF private/intermediate.key.pem -r-------- 1 root root 3.3K Jun 20 16:30 private/intermediate.key.pem [root@c7u6s2 CA]#
使用前面生成的私钥文件生成对应的证书签发请求文件,具体如下所示:
[root@c7u6s2 CA]# openssl req -config openssl.cnf -new -sha256 -key private/intermediate.key.pem -out csr/intermediate.csr.pem Enter pass phrase for private/intermediate.key.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) [CN]: State or Province Name [Beijing]: Locality Name []:Beijing Organization Name [LiuXianQiE Ltd]: Organizational Unit Name [Root CA]: Common Name []:LiuXianQiE Ltd Root CA Email Address []: [root@c7u6s2 CA]# ls certs crl csr newcerts openssl.cnf private [root@c7u6s2 CA]# cd csr/ [root@c7u6s2 csr]# ls intermediate.csr.pem [root@c7u6s2 csr]# ll -h total 4.0K -rw-r--r-- 1 root root 1.7K Jun 20 16:34 intermediate.csr.pem [root@c7u6s2 csr]#
将上一步操作中生成的证书签发请求文件发送给根CA,并在根CA上完成证书签署操作。具体如下所示:
[root@c7u6s2 csr]# rsync -av --progress -e 'ssh -p 22 -l root' intermediate.csr.pem c7u6s1:~ root@c7u6s1's password: sending incremental file list intermediate.csr.pem 1,728 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=0/1) sent 1,834 bytes received 35 bytes 415.33 bytes/sec total size is 1,728 speedup is 0.92 [root@c7u6s2 csr]#
接下来在根CA上使用中间CA的证书签发请求给其签发证书,注意,此处需要使用根前面使用过的根CA的配置文件。
下面是在c7u6s1这台根CA上执行证书签署操作,具体如下:
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 16 (0x10) Validity Not Before: Jun 20 08:45:21 2021 GMT Not After : Jun 20 08:45:21 2022 GMT Subject: countryName = CN stateOrProvinceName = Beijing organizationName = LiuXianQiE Ltd organizationalUnitName = Root CA commonName = LiuXianQiE Ltd Root CA Certificate is to be certified until Jun 20 08:45:21 2022 GMT (365 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 Data Base Updated [root@c7u6s1 CA]# ls certs crl index.txt index.txt.attr index.txt.old newcerts openssl.cnf private serial serial.old [root@c7u6s1 CA]# ls certs/ ca.cert.pem intermediate.cert.pem [root@c7u6s1 CA]# ls -lh certs/intermediate.cert.pem -rw-r--r-- 1 root root 1.9K Jun 20 16:45 certs/intermediate.cert.pem [root@c7u6s1 CA]# chmod 444 certs/intermediate.cert.pem [root@c7u6s1 CA]# ls -lh certs/intermediate.cert.pem -r--r--r-- 1 root root 1.9K Jun 20 16:45 certs/intermediate.cert.pem [root@c7u6s1 CA]# ls certs crl index.txt index.txt.attr index.txt.old newcerts openssl.cnf private serial serial.old [root@c7u6s1 CA]#
在根CA上对签发的证书进行验证,具体如下所示:
[root@c7u6s1 CA]# openssl x509 -noout -text -in certs/intermediate.cert.pem Certificate: Data: Version: 1 (0x0) Serial Number: 16 (0x10) Signature Algorithm: sha256WithRSAEncryption Issuer: C=CN, ST=Beijing, L=beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA Validity Not Before: Jun 20 08:45:21 2021 GMT Not After : Jun 20 08:45:21 2022 GMT Subject: C=CN, ST=Beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:b3:d2:da:6c:a0:c8:ec:47:2a:de:8c:98:92:24: cd:d5:93:3a:97:e7:32:fd:12:3f:b8:1a:0f:ab:da: 5c:38:76:ee:c7:55:27:45:b5:0a:9c:a0:a9:7e:91: 33:7b:59:ad:ec:c2:20:c4:64:ae:8e:a2:9c:b2:94: 59:a5:69:d7:ee:e1:c5:9b:f2:29:4f:8c:d5:0d:23: e8:71:e2:04:b2:70:71:51:cb:ae:8c:a1:1d:48:92: c2:3e:df:34:f4:08:dd:fb:1c:db:e7:bd:f7:b8:d7: 45:3a:5b:35:eb:16:2e:29:d9:60:98:2f:96:87:6b: 8e:cf:1f:91:1c:10:1c:2d:c7:29:ad:bd:b5:00:2c: 76:3e:96:2f:f5:fe:96:ca:bf:59:35:25:7f:c1:1c: 6a:73:b6:71:aa:f7:86:0b:99:93:f8:6c:cb:ce:81: 43:98:1e:cf:78:79:8d:f7:47:60:5a:5e:2d:22:cb: 0b:0e:ac:a6:68:2c:65:c9:13:31:1f:63:72:1f:02: 42:e1:84:75:6a:cb:a1:70:8c:3a:ac:4b:81:ef:5d: b2:a7:df:ea:c9:fd:21:2f:bb:1a:83:e8:91:20:22: a2:bf:02:73:78:29:39:f7:71:92:b7:ae:cb:68:cd: 48:8f:5c:8c:cf:4f:83:91:92:d3:2c:bd:6f:d2:c2: f0:b6:c4:82:5f:fb:0e:9c:49:9a:77:26:bf:55:4a: 26:64:95:b9:7e:ad:26:0c:d0:96:f4:bb:e1:f4:57: 57:97:c8:78:30:45:14:da:d6:3b:3e:2c:23:ea:7f: 39:f1:42:7e:79:84:22:06:07:40:5c:e2:46:62:fe: 96:bf:61:4d:02:6b:d0:2b:19:bf:bd:d9:09:47:c7: f7:01:71:5d:15:5e:ad:96:df:99:06:77:60:07:c6: aa:e9:5e:1c:13:80:90:f0:d1:05:1f:4d:aa:9c:9d: a8:1a:a5:f3:c6:3a:fe:52:71:9f:e2:f0:d9:9b:c3: cf:86:a7:79:e0:53:8a:b6:0d:47:66:87:23:8a:af: 7b:99:ff:d8:05:77:b9:ac:66:8f:41:2a:45:0b:47: 53:46:e8:4d:bb:3d:c0:71:27:a8:df:5d:14:f8:53: ad:fe:41:f6:47:1c:93:e9:0a:1b:a7:45:3e:fd:c6: 06:40:01:03:3a:2e:3c:71:3b:dc:ae:a9:5e:66:7d: 20:a3:aa:67:67:35:59:f6:fe:f8:54:73:a1:89:fc: 28:12:85:70:d1:d5:ec:2f:16:ee:21:77:64:6d:d7: d6:76:e4:f6:52:97:a6:17:d0:a3:9c:2d:c3:48:49: 9c:30:35:e1:f6:3d:6a:f7:64:0f:e0:bc:27:3f:f5: 1d:de:05 Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption 50:a6:cb:62:55:a5:21:48:61:72:16:f3:89:2c:92:71:88:5a: 6c:92:51:43:dc:b5:98:d8:89:2c:d0:af:b8:44:48:80:dd:8d: 0d:db:74:a3:ae:90:6b:8e:5f:8f:03:de:ac:e5:7b:77:a3:ed: b0:21:48:18:5a:59:72:18:37:20:8b:a4:70:e4:dd:e8:92:fb: 03:fd:50:2e:a7:6a:9d:57:5f:fe:a5:48:8c:6d:88:65:8f:14: bc:2a:fd:6b:b5:75:c0:4a:ad:c7:c8:27:2a:91:2a:10:b5:60: 71:fa:44:fd:84:c2:f1:9a:3d:6e:97:15:8b:66:82:52:b8:03: b2:4a:58:a6:dd:4b:6c:f7:13:5c:57:75:7b:40:67:74:c1:61: d3:bc:90:16:39:8e:17:d6:32:09:1b:99:f6:63:4b:62:b5:22: cb:8f:9b:8e:b6:f3:44:66:07:7c:43:78:11:04:4e:86:91:51: c9:cb:44:c1:7d:e5:51:02:36:69:ab:34:18:b1:fc:08:95:79: 13:c3:48:cd:fd:72:ee:3a:81:2a:fa:a4:96:b7:86:62:48:0c: c5:bc:c9:f5:22:82:fb:d5:16:d9:3a:da:7e:54:6b:95:b5:76: c2:fd:0b:8b:25:67:af:70:6e:cf:43:69:76:5c:c4:fa:02:3d: 3a:70:ae:a4:d1:70:a6:7d:b7:f0:93:76:cd:eb:72:ba:36:b2: 71:26:38:4d:cb:d1:22:43:f6:f3:30:ce:c9:69:2c:61:64:88: 96:13:2e:0f:7c:47:55:56:b7:66:ed:53:79:6b:ad:05:8c:42: db:27:0d:88:02:2d:93:a5:36:ce:ce:2d:1e:92:04:3d:04:76: fe:83:c6:54:72:d8:4c:83:16:9d:78:88:d5:80:e6:c3:63:ef: 2e:71:93:f0:9d:8d:44:e2:cc:6d:3f:fe:b5:63:4e:55:0c:c6: c3:23:b6:b1:bf:49:d0:0e:42:3d:54:e2:ce:e0:5d:12:4c:55: 04:a9:f4:0c:ba:40:bc:96:b3:ae:ed:35:b2:2b:5a:b8:e9:b8: dd:a0:16:3c:c7:b4:b9:b4:b9:9f:7c:e7:bd:a3:2b:f3:a9:15: ce:a7:90:1d:79:35:2f:d0:19:22:ee:ee:e4:30:ac:77:ec:9b: 90:31:c5:4c:3d:05:d9:23:b2:67:95:78:18:1f:20:8c:50:20: 90:7b:af:f6:9d:1d:26:82:1c:34:74:e7:ba:62:20:59:b9:6f: 0b:00:91:5e:5c:ea:da:c2:b2:83:46:9e:5e:17:4f:6d:95:c6: 15:8e:f1:a9:e2:c3:5e:3a [root@c7u6s1 CA]# openssl x509 -noout -dates -in certs/intermediate.cert.pem notBefore=Jun 20 08:45:21 2021 GMT notAfter=Jun 20 08:45:21 2022 GMT [root@c7u6s1 CA]# openssl x509 -noout -issuer -in certs/intermediate.cert.pem issuer= /C=CN/ST=Beijing/L=beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# openssl x509 -noout -subject -in certs/intermediate.cert.pem subject= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# ls certs/ ca.cert.pem intermediate-1.cert.pem intermediate.cert.pem [root@c7u6s1 CA]# [root@c7u6s1 CA]# openssl verify -CAfile certs/ca.cert.pem certs/intermediate.cert.pem certs/intermediate.cert.pem: OK [root@c7u6s1 CA]#
上面签发完证书之后,可以看出,增加了一些文件:“index.txt.attr, index.txt.old, serial.old”。查看这几个文件以及变化之前的文件内容,如下所示:
# index.txt的变化情况如下所示: [root@c7u6s1 CA]# cat index.txt V 220620084521Z 10 unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# cat index.txt.attr unique_subject = yes [root@c7u6s1 CA]# cat index.txt.old [root@c7u6s1 CA]# # serial文件的变化情况如下所示: [root@c7u6s1 CA]# cat serial 11 [root@c7u6s1 CA]# cat serial.old 10 [root@c7u6s1 CA]#
可以看出,index.txt.old是最初我们手动创建的一个空文件,而新的index.txt这个文件中记录根CA签发过的证书信息,比如证书序号等。而index.txt.attr这个文件则记录了签发操作的基本属性,unique_subject = yes
表示一个证书签发请求文件只能对应生成一个证书文件,不能使用一个证书签发请求文件生成两个证书,具体如下所示:
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate-1.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 17 (0x11) Validity Not Before: Jun 20 09:11:15 2021 GMT Not After : Jun 20 09:11:15 2022 GMT Subject: countryName = CN stateOrProvinceName = Beijing organizationName = LiuXianQiE Ltd organizationalUnitName = Root CA commonName = LiuXianQiE Ltd Root CA Certificate is to be certified until Jun 20 09:11:15 2022 GMT (365 days) Sign the certificate? [y/n]:y failed to update database TXT_DB error number 2 [root@c7u6s1 CA]#
上述提示更新数据库失败。证书签发失败。如果将上面的index.txt.attr中的对应属性unique_subject = yes
修改为no,那么就会允许执行上述操作。具体如下所示:
[root@c7u6s1 CA]# vim index.txt.attr [root@c7u6s1 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/intermediate.csr.pem -out certs/intermediate-1.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 17 (0x11) Validity Not Before: Jun 20 09:12:53 2021 GMT Not After : Jun 20 09:12:53 2022 GMT Subject: countryName = CN stateOrProvinceName = Beijing organizationName = LiuXianQiE Ltd organizationalUnitName = Root CA commonName = LiuXianQiE Ltd Root CA Certificate is to be certified until Jun 20 09:12:53 2022 GMT (365 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 Data Base Updated [root@c7u6s1 CA]# ls -lh certs/ total 12K -rw-r--r-- 1 root root 2.1K Jun 20 16:23 ca.cert.pem -rw-r--r-- 1 root root 1.9K Jun 20 17:12 intermediate-1.cert.pem -rw-r--r-- 1 root root 1.9K Jun 20 16:45 intermediate.cert.pem [root@c7u6s1 CA]# [root@c7u6s1 CA]# cat index.txt.attr unique_subject = no [root@c7u6s1 CA]#
将intermediate-1.cert.pem这个证书吊销,然后将index.txt.attr这个文件改回yes状态,执行如下命令即可:
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -revoke certs/intermediate-1.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: Revoking Certificate 11. Data Base Updated [root@c7u6s1 CA]# [root@c7u6s1 CA]# vim index.txt.attr [root@c7u6s1 CA]# cat index.txt.attr unique_subject = yes [root@c7u6s1 CA]#
如果先改回yes状态,然后执行吊销,此时就无法执行吊销操作,甚至无法执行创建吊销列表的操作,具体如下所示:
[root@c7u6s1 CA]# openssl ca -config openssl.cnf -revoke certs/intermediate-1.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: error creating name index:(2,0,1) [root@c7u6s1 CA]# [root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: error creating name index:(2,0,1) [root@c7u6s1 CA]#
上面无论是执行证书吊销操作,还是执行创建吊销列表的操作,都无法执行,且报错相同,都是无法创建名称索引。这个问题就是由于先将index.txt.attr中的属性从yes该为no之后,使用相同的证书签发请求文件创建了第二个整数,然后就将index.txt.attr中的属性从no又改回了yes状态导致的。再次将yes改回no,然后就可以执行证书吊销操作就可以正常完成了。
要执行吊销列表创建操作,需要在当前目录创建一个名为crlnumber(这个文件名以及下面的吊销列表的名称,都是在openssl.cnf这个文件中记录的)的文件,其中可以随便指定一个吊销序号,具体如下所示:
[root@c7u6s1 CA]# touch crlnumber [root@c7u6s1 CA]# ls certs crl crlnumber index.txt index.txt.attr index.txt.attr.old index.txt.old newcerts openssl.cnf private serial serial.old [root@c7u6s1 CA]# ls crl [root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: unable to load number from /etc/pki/CA/crlnumber error while loading CRL number 140282462922640:error:0D066096:asn1 encoding routines:a2i_ASN1_INTEGER:short line:f_int.c:210: [root@c7u6s1 CA]# echo 10 > crlnumber [root@c7u6s1 CA]# openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/ca.key.pem: [root@c7u6s1 CA]# ls crl ca.crl.pem [root@c7u6s1 CA]# cat crlnumber 11 [root@c7u6s1 CA]#
上述就完成了证书吊销列表的创建操作。
虽然intermediate-1.cert.pem这个证书已经被吊销,但是其并不会被自动删除。
吊销证书之后,此时CA目录中文件的变化情况如下所示:
[root@c7u6s1 CA]# ls certs crlnumber index.txt index.txt.attr.old newcerts private serial.old crl crlnumber.old index.txt.attr index.txt.old openssl.cnf serial [root@c7u6s1 CA]# cat index.txt V 220620084521Z 10 unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA R 220620091253Z 210620093349Z 11 unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# cat index.txt.attr unique_subject = yes [root@c7u6s1 CA]# cat index.txt.attr.old unique_subject = no [root@c7u6s1 CA]# cat index.txt.old V 220620084521Z 10 unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA V 220620091253Z 11 unknown /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s1 CA]# [root@c7u6s1 CA]# cat serial 12 [root@c7u6s1 CA]# cat serial.old 11 [root@c7u6s1 CA]#
可以看出,index.txt文件中,将被吊销的证书前面从V改成了R(V表示Valid,有效的;R表示Revoked,被吊销的)。
当应用程序尝试验证中间CA签发的证书的时候,必然也会对给中间CA签发整数的根CA进行验证。为了实现链式信任,所以需要创建一个证书链文件并传给应用程序。要创建证书链文件,需要将根CA的证书和中间CA的证书合并在一起生成一个证书链文件,具体过程如下所示:
[root@c7u6s1 CA]# cat certs/intermediate.cert.pem certs/ca.cert.pem > certs/intermediate-root.cert.pem [root@c7u6s1 CA]# ls -lhF certs/intermediate-root.cert.pem -rw-r--r-- 1 root root 4.0K Jun 20 18:33 certs/intermediate-root.cert.pem [root@c7u6s1 CA]#
至此,证书链文件就创建完成了。
有了上述根CA签发的证书以及证书链文件,将这个文件部署到中间CA的/etc/pki/CA/certs/
这个目录中,中间CA就可以代表根CA对服务器进行证书签署了。
[root@c7u6s1 CA]# rsync -av --progress -e 'ssh -p 22 -l root' certs/{intermediate.cert.pem,intermediate-root.cert.pem} c7u6s2:~ The authenticity of host 'c7u6s2 (192.168.122.12)' can't be established. ECDSA key fingerprint is SHA256:haaw1q6jKB6Gijmwapks1oMX8hSqub7AusDLPhErXxQ. ECDSA key fingerprint is MD5:c3:c6:39:87:37:52:b7:38:40:1c:78:a2:40:a4:9e:4d. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'c7u6s2,192.168.122.12' (ECDSA) to the list of known hosts. root@c7u6s2's password: sending incremental file list intermediate-root.cert.pem 4,017 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=1/2) intermediate.cert.pem 1,919 100% 1.83MB/s 0:00:00 (xfr#2, to-chk=0/2) sent 6,118 bytes received 54 bytes 1,122.18 bytes/sec total size is 5,936 speedup is 0.96 [root@c7u6s1 CA]#
然后将这两个文件放在中间CA的对应证书目录中,具体如下所示:
[root@c7u6s2 CA]# ls -lhF ~/intermediate* -r--r--r-- 1 root root 1.9K Jun 20 16:45 /root/intermediate.cert.pem -rw-r--r-- 1 root root 4.0K Jun 20 18:33 /root/intermediate-root.cert.pem [root@c7u6s2 CA]# cp ~/intermediate{.cert.pem,-root.cert.pem} ./certs/ [root@c7u6s2 CA]# ls ./certs/ intermediate.cert.pem intermediate-root.cert.pem [root@c7u6s2 CA]# ls private/ intermediate.key.pem [root@c7u6s2 CA]#
至此,根CA以及中间CA就部署完成了。
由于服务器向中间CA申请证书的时候,不可能将自己的私钥文件发送给中间CA,所以就需要在服务器上先生成自己的私钥文件,然后用私钥文件生成证书签发请求文件。最后将证书签发请求文件发送给中间CA,并由中间CA完成证书签署操作之后,将签署的证书和证书链文件发送给服务器。具体过程如下所示:
[root@c7u6s3 ~]# mkdir certificates [root@c7u6s3 ~]# cd certificates [root@c7u6s3 certificates]# ls [root@c7u6s3 certificates]# openssl genrsa -aes256 -out www.example.com.key.pem 2048 Generating RSA private key, 2048 bit long modulus .......................................................................................................+++ ......................................+++ e is 65537 (0x10001) Enter pass phrase for www.example.com.key.pem: Verifying - Enter pass phrase for www.example.com.key.pem: [root@c7u6s3 certificates]# ls www.example.com.key.pem [root@c7u6s3 certificates]# ls -lh www.example.com.key.pem -rw-r--r-- 1 root root 1.8K Jun 21 01:03 www.example.com.key.pem [root@c7u6s3 certificates]# chmod 400 www.example.com.key.pem [root@c7u6s3 certificates]# ls -lhF www.example.com.key.pem -r-------- 1 root root 1.8K Jun 21 01:03 www.example.com.key.pem [root@c7u6s3 certificates]#
此处私钥的对称加密密钥长度设置为2048,这也是大多数互联网公司的证书密钥长度,对于证书有效期为1年的证书,这个长度足够了。如果使用4096位长度的密钥,那么在TLS握手阶段将会增加CPU的开销。
上述就完成了发起证书签发请求的服务器上的私钥生成。接下来生成证书签发请求文件,并发送给中间CA,让其进行证书签发操作。
在服务器上使用前面生成的私钥文件,生成对应的证书签发请求文件,具体如下所示:
[root@c7u6s3 certificates]# openssl req -key ./www.example.com.key.pem -new -sha256 -out www.example.com.csr.pem Enter pass phrase for ./www.example.com.key.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) [XX]:CN State or Province Name (full name) []:Beijing Locality Name (eg, city) [Default City]:beijing Organization Name (eg, company) [Default Company Ltd]:Example ltd Organizational Unit Name (eg, section) []:IT Common Name (eg, your name or your server's hostname) []:www.example.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: [root@c7u6s3 certificates]# ls www.example.com.csr.pem www.example.com.key.pem [root@c7u6s3 certificates]# ls -lhF ./* -rw-r--r-- 1 root root 1013 Jun 21 01:07 ./www.example.com.csr.pem -r-------- 1 root root 1.8K Jun 21 01:03 ./www.example.com.key.pem [root@c7u6s3 certificates]#
上述就完成了证书签发请求服务器上的证书签发请求文件生成操作,随后将这个证书签发请求文件发送给中间CA之后,中间CA就可以根据这个证书签发请求文件完成证书签发操作。
将上述文件拷贝到中间CA,即c7u6s2这台虚拟机上。具体如下所示:
[root@c7u6s3 certificates]# rsync -av --progress -e 'ssh -p 22 -l root' www.example.com.csr.pem c7u6s2:~ The authenticity of host 'c7u6s2 (192.168.122.12)' can't be established. ECDSA key fingerprint is SHA256:haaw1q6jKB6Gijmwapks1oMX8hSqub7AusDLPhErXxQ. ECDSA key fingerprint is MD5:c3:c6:39:87:37:52:b7:38:40:1c:78:a2:40:a4:9e:4d. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'c7u6s2,192.168.122.12' (ECDSA) to the list of known hosts. root@c7u6s2's password: sending incremental file list www.example.com.csr.pem 1,013 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=0/1) sent 1,122 bytes received 35 bytes 100.61 bytes/sec total size is 1,013 speedup is 0.88 [root@c7u6s3 certificates]#
服务器的证书签发请求文件生成完毕,并且传送到了中间CA上。
查看接收到的证书签发请求文件,具体如下所示:
[root@c7u6s2 ~]# ls -lhF www.example.com.csr.pem -rw-r--r-- 1 root root 1013 Jun 21 01:07 www.example.com.csr.pem [root@c7u6s2 ~]#
接下来使用中间CA的配置文件完成上述证书签发
[root@c7u6s2 ~]# cd /etc/pki/CA/ [root@c7u6s2 CA]# ls certs crl csr newcerts openssl.cnf private [root@c7u6s2 CA]# touch index.txt [root@c7u6s2 CA]# echo 10 > serial [root@c7u6s2 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/www.example.com.csr.pem -out certs/www.example.com.cert.pem Using configuration from openssl.cnf Error opening CA private key /root/intermediate-ca/ca/private/intermediate.key.pem 140280877381520:error:02001002:system library:fopen:No such file or directory:bss_file.c:402:fopen('/root/intermediate-ca/ca/private/intermediate.key.pem','r') 140280877381520:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:404: unable to load CA private key [root@c7u6s2 CA]# vim openssl.cnf [root@c7u6s2 CA]# openssl ca -config openssl.cnf -days 365 -notext -md sha256 -in ~/www.example.com.csr.pem -out certs/www.example.com.cert.pem Using configuration from openssl.cnf Enter pass phrase for /etc/pki/CA/private/intermediate.key.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 16 (0x10) Validity Not Before: Jun 20 17:16:20 2021 GMT Not After : Jun 20 17:16:20 2022 GMT Subject: countryName = CN stateOrProvinceName = Beijing localityName = beijing organizationName = Example ltd organizationalUnitName = IT commonName = www.example.com Certificate is to be certified until Jun 20 17:16:20 2022 GMT (365 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 Data Base Updated [root@c7u6s2 CA]#
第一次执行签发命令openssl ca
的时候报错,提示没找到中间CA的私钥文件,这是因为我们的中间CA的配置文件中记录了CA的路径与实际的私钥存放路径不一致导致的,修改配置文件openssl.cnf中的路径即可。具体如下所示:
[root@c7u6s2 CA]# cat openssl.cnf | head -n15 # OpenSSL intermediate CA configuration file. # Copy to `/root/ca/intermediate/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /etc/pki/CA certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial [root@c7u6s2 CA]#
上述的配置文件前15行中,[ ca ]
指定了默认的CA操作,采用[ CA_default ]
中的定义,而这其中dir = /etc/pki/CA
就定义了CA的证书根路径,下面是对应的证书的具体路径、吊销列表路径、新证书路径、数据库以及序列号文件等的具体路径信息。
修改为正确的路径信息之后,就可以正常签发证书了。
中间CA完成了服务器端的证书签署操作,查看签署完成的证书,如下所示:
[root@c7u6s2 CA]# openssl x509 -noout -text -in certs/www.example.com.cert.pem Certificate: Data: Version: 1 (0x0) Serial Number: 16 (0x10) Signature Algorithm: sha256WithRSAEncryption Issuer: C=CN, ST=Beijing, O=LiuXianQiE Ltd, OU=Root CA, CN=LiuXianQiE Ltd Root CA Validity Not Before: Jun 20 17:16:20 2021 GMT Not After : Jun 20 17:16:20 2022 GMT Subject: C=CN, ST=Beijing, L=beijing, O=Example ltd, OU=IT, CN=www.example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c0:6f:fe:65:c5:2f:1b:d9:6c:5c:f5:cd:20:51: e0:ca:a4:23:ca:d2:5a:df:58:60:e6:72:1a:e4:c9: a2:7d:ec:5d:6a:94:5f:9a:fe:bb:6d:51:0b:6e:c0: dc:90:cd:4d:95:6e:55:db:df:ad:9e:83:b4:14:34: b1:4f:e9:61:9d:5d:54:1d:80:c6:94:11:e7:aa:8d: 7d:16:a6:ca:24:e9:67:1d:c2:3a:a6:2a:ef:88:ef: 11:9d:0e:c2:cd:42:04:21:ad:62:42:38:66:7f:4d: 72:f4:a6:ad:ce:89:08:8a:75:35:40:b8:47:e0:04: 25:e7:af:df:6e:03:5a:e7:d6:1b:55:48:23:1d:48: 08:7f:e3:be:54:6f:c5:ac:6f:20:52:4d:d5:23:a4: 19:b1:fb:b2:4c:e7:7f:9c:60:8a:56:68:ec:29:21: 26:37:a9:f8:13:ab:dc:3d:74:52:6d:4e:96:3d:6c: 40:00:83:38:ad:3b:a2:aa:63:ab:33:cf:c5:e6:1e: 7f:bd:01:22:f2:bf:4f:b4:07:db:e3:84:28:c6:a5: 4b:26:75:41:94:ff:fa:71:f7:f4:8b:ee:e1:b9:ce: 85:0e:1f:19:0e:42:8f:4b:3b:99:5f:7a:5e:78:ac: 27:88:54:db:f8:9f:6f:fa:c5:2f:03:bd:5a:1a:e8: f0:cd Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption 89:c7:2f:90:5b:4f:67:61:bd:e7:68:7b:6a:4d:b3:df:4b:22: c4:98:87:c4:60:e6:39:3d:09:1a:23:96:be:de:51:59:b5:9e: 1d:85:7a:7d:6d:fd:03:84:03:46:71:56:7b:0d:a4:5c:a7:97: 53:60:58:d9:05:b1:f5:b8:17:cf:1d:42:7b:3d:1c:23:cd:be: 76:5a:20:7e:3d:a7:cd:d7:12:c0:90:ac:89:40:f8:5e:74:d2: ad:32:5d:7a:67:97:bf:9b:0d:3a:58:b4:0b:a0:8c:d5:b1:56: f2:a7:e2:fd:54:04:f8:55:a7:df:ea:50:ba:88:c8:5f:44:ad: 12:59:c2:40:0a:70:34:7a:b9:66:7a:cf:9a:6d:8d:1b:c5:09: fa:ef:59:14:4a:f5:b0:5f:7f:2a:02:19:ee:dc:81:48:3f:60: 8b:bd:b3:57:4b:b1:5b:12:4d:fb:b4:5c:96:db:a3:ac:f1:8d: 52:4c:ca:2a:3c:f0:e2:fe:2f:54:fa:2c:bf:ad:1b:cb:59:95: 96:9f:d9:48:ec:53:55:82:b9:c6:3c:db:ef:54:38:2c:0b:e8: 7e:53:5e:85:ee:e4:16:a4:af:9b:29:29:59:fe:f2:19:d8:51: 67:0c:b0:a0:b2:4b:68:e7:4c:1a:15:cf:68:52:6e:e7:7e:a3: cf:50:34:26:32:15:a4:f9:20:09:73:cf:45:62:b9:c1:b8:47: ec:81:a2:18:4f:e2:76:2c:aa:38:e8:66:36:bc:56:a5:25:85: 74:3a:bd:9b:b7:5a:df:68:bd:4d:c4:43:26:9a:1f:06:a4:7c: b5:3e:76:ba:b1:a7:71:0b:ca:b5:f8:63:d4:19:25:83:41:30: ad:ff:a4:4f:35:63:37:e2:a7:75:0b:28:61:ef:8a:cb:6c:d7: 9d:7c:93:63:bd:15:08:5b:95:fb:94:59:f8:2c:c5:32:44:49: 6e:0f:45:ed:ba:18:1d:90:35:8b:52:62:16:21:bf:ab:cc:d5: e8:9f:e6:fa:83:3b:42:be:c1:12:57:80:50:c2:bc:50:c0:1e: 7b:95:09:b1:34:7e:d9:ac:e0:da:09:ef:e0:59:02:fa:42:c1: 2f:07:5e:2e:c9:c6:a7:32:1f:38:ec:af:d5:a6:75:33:a2:a6: dc:20:35:26:34:22:cb:87:3d:6d:bd:3c:29:45:d7:4f:97:34: 6e:54:e1:67:4a:3b:05:ce:96:8a:bb:84:00:39:98:38:9b:05: e4:cb:51:49:5a:9b:b9:f2:46:25:b9:f8:97:56:b8:98:10:81: 0e:8f:5e:ba:fb:da:49:e6:bd:2b:5b:f1:f8:6b:ea:3a:09:a1: 3c:2e:76:04:c7:71:77:a3 [root@c7u6s2 CA]# openssl x509 -noout -dates -in certs/www.example.com.cert.pem notBefore=Jun 20 17:16:20 2021 GMT notAfter=Jun 20 17:16:20 2022 GMT [root@c7u6s2 CA]# openssl x509 -noout -issuer -in certs/www.example.com.cert.pem issuer= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s2 CA]# openssl x509 -noout -subject -in certs/www.example.com.cert.pem subject= /C=CN/ST=Beijing/L=beijing/O=Example ltd/OU=IT/CN=www.example.com [root@c7u6s2 CA]# [root@c7u6s2 CA]# openssl verify -CAfile certs/intermediate-root.cert.pem certs/www.example.com.cert.pem certs/www.example.com.cert.pem: OK [root@c7u6s2 CA]#
证书签发完成,状态OK。上述最后的openssl verify
命令中通过-CAfile certs/intermediate-root.cert.pem
选项指定的文件是证书链文件,即此前根CA给中间CA签发证书的时候,连同着签署的证书一起将证书链发送给中间CA,以便证明CA的签发关系和合法性。
接下来将中间CA签发好的证书连同证书链一并发送给发起证书签发请求的c7u6s3这个服务器,具体如下所示:
[root@c7u6s2 CA]# ls certs/ intermediate.cert.pem intermediate-root.cert.pem www.example.com.cert.pem [root@c7u6s2 CA]# rsync -av --progress -e 'ssh -p 22 -l root' certs/{intermediate-root.cert.pem,www.example.com.cert.pem} c7u6s3:/root/certificates The authenticity of host 'c7u6s3 (192.168.122.13)' can't be established. ECDSA key fingerprint is SHA256:HEaDOd4KItgL244FPiBzYyqzb+Sg/RIpsNG/oNiQUvg. ECDSA key fingerprint is MD5:75:f3:2c:e7:e3:f7:42:93:28:c7:aa:d9:0b:28:6a:37. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'c7u6s3,192.168.122.13' (ECDSA) to the list of known hosts. root@c7u6s3's password: sending incremental file list intermediate-root.cert.pem 4,017 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=1/2) www.example.com.cert.pem 1,554 100% 1.48MB/s 0:00:00 (xfr#2, to-chk=0/2) sent 5,764 bytes received 54 bytes 1,057.82 bytes/sec total size is 5,571 speedup is 0.96 [root@c7u6s2 CA]#
在证书签发申请服务器上查看签发好的证书和证书链,具体如下所示:
[root@c7u6s3 certificates]# ls -lhF ./* -rw-r--r-- 1 root root 4.0K Jun 20 18:37 ./intermediate-root.cert.pem -rw-r--r-- 1 root root 1.6K Jun 21 01:16 ./www.example.com.cert.pem -rw-r--r-- 1 root root 1013 Jun 21 01:07 ./www.example.com.csr.pem -r-------- 1 root root 1.8K Jun 21 01:03 ./www.example.com.key.pem [root@c7u6s3 certificates]# [root@c7u6s3 certificates]# openssl x509 -noout -dates -in www.example.com.cert.pem notBefore=Jun 20 17:16:20 2021 GMT notAfter=Jun 20 17:16:20 2022 GMT [root@c7u6s3 certificates]# openssl x509 -noout -issuer -in www.example.com.cert.pem issuer= /C=CN/ST=Beijing/O=LiuXianQiE Ltd/OU=Root CA/CN=LiuXianQiE Ltd Root CA [root@c7u6s3 certificates]# openssl x509 -noout -subject -in www.example.com.cert.pem subject= /C=CN/ST=Beijing/L=beijing/O=Example ltd/OU=IT/CN=www.example.com [root@c7u6s3 certificates]# openssl verify -CAfile intermediate-root.cert.pem www.example.com.cert.pem www.example.com.cert.pem: OK [root@c7u6s3 certificates]#
上述就完成了在证书签发申请服务器上的证书验证和查看。现在就具有了4个文件:
至此,私有CA设置以及证书签署操作就完成了。
ssh客户端常用的一个参数是StrickHostKeyChecking
,这个参数的作用是在初次建立到某个主机的连接的时候,将对象主机的公钥添加到本地的.ssh/known_hsots
这个文件中。初次建立连接的时候会有一个询问过程,这是因为这个参数StrictHostKeyChecking ask
的缘故,如果不想要这个询问的交互过程,可以将这个参数的值修改为no即可。这个参数支持3个有效的值,分别为ask, yes, no
:
.ssh/known_hosts
文件中的任何主机,并且不会自动将目标主机的公钥添加到上述文件中。.ssh/known_hosts
这个文件中。.ssh/known_hosts
配置文件中。[root@c7u6s4 ~]# ls .ssh/ authorized_keys id_rsa id_rsa.pub [root@c7u6s4 ~]# ssh c7u6s6 The authenticity of host 'c7u6s6 (192.168.122.16)' can't be established. ECDSA key fingerprint is SHA256:Rn3dya2SjkXHSugIk+//fvGGNkdRFTfnLbortO+5FOU. ECDSA key fingerprint is MD5:e5:7d:10:15:0e:52:a1:8b:bb:d1:3a:d8:c1:29:41:3c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'c7u6s6,192.168.122.16' (ECDSA) to the list of known hosts. root@c7u6s6's password: Last login: Fri Jun 18 18:56:04 2021 from 192.168.122.1 [root@c7u6-ha1 ~]# cat .ssh/known_hosts ubuntu20u04,192.168.122.30 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJS3FPX8mGgBeW/E9f//eoM9SZfTr1z5s7xkqBuzdD/LJw8v0WNcqBeLOwn7+/e9yEvgxhig4Ol9IjHhx8zZIKc= [root@c7u6-ha1 ~]# exit logout Connection to c7u6s6 closed. [root@c7u6s4 ~]# cat .ssh/known_hosts c7u6s6,192.168.122.16 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbnlzdHAyNTYAAABBBFQpwM5m3BoID+u8HOY5a/IRpbIQxUEWlTDFTjsMnUrhtjZO8Wc9DQXG2bruO19EZHmg2g+XDCIjVfmsu4Gd1OE= [root@c7u6s4 ~]#
要改变这个命令参数,有两种方式:
-o StrictHostKeyChecking=no
来改变[root@c7u6s4 ~]# ls .ssh/ authorized_keys id_rsa id_rsa.pub known_hosts [root@c7u6s4 ~]# rm .ssh/known_hosts -f [root@c7u6s4 ~]# ls .ssh/ authorized_keys id_rsa id_rsa.pub [root@c7u6s4 ~]# ssh -o StrictHostKeyChecking=no c7u6s6 Warning: Permanently added 'c7u6s6,192.168.122.16' (ECDSA) to the list of known hosts. root@c7u6s6's password: Last login: Tue Jun 22 07:25:33 2021 from 192.168.122.14 [root@c7u6-ha1 ~]# exit logout Connection to c7u6s6 closed. [root@c7u6s4 ~]# ls -lh .ssh/known_hosts -rw-r--r-- 1 root root 183 Jun 22 07:28 .ssh/known_hosts [root@c7u6s4 ~]# cat .ssh/known_hosts c7u6s6,192.168.122.16 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbnlzdHAyNTYAAABBBFQpwM5m3BoID+u8HOY5a/IRpbIQxUEWlTDFTjsMnUrhtjZO8Wc9DQXG2bruO19EZHmg2g+XDCIjVfmsu4Gd1OE= [root@c7u6s4 ~]#
/etc/ssh/ssh_config
来改变[root@c7u6s4 ~]# ls .ssh/ authorized_keys id_rsa id_rsa.pub known_hosts [root@c7u6s4 ~]# rm -f .ssh/known_hosts [root@c7u6s4 ~]# vim /etc/ssh/ssh_config [root@c7u6s4 ~]# cat /etc/ssh/ssh_config | egrep Strict StrictHostKeyChecking no [root@c7u6s4 ~]# ls .ssh/ authorized_keys id_rsa id_rsa.pub [root@c7u6s4 ~]# ssh c7u6s6 Warning: Permanently added 'c7u6s6,192.168.122.16' (ECDSA) to the list of known hosts. root@c7u6s6's password: Last login: Tue Jun 22 07:28:57 2021 from 192.168.122.14 [root@c7u6-ha1 ~]# exit logout Connection to c7u6s6 closed. [root@c7u6s4 ~]# ls .ssh authorized_keys id_rsa id_rsa.pub known_hosts [root@c7u6s4 ~]#
客户端连接服务器的时候,基本这个选项参数是最常用的,尤其在新设置的主机上,初次建立连接的时候。更多的ssh客户端的参数解释,参见man ssh_config
。
ssh服务器端的配置文件位于/etc/ssh/sshd_config
,这个文件中记录了服务器相关参数设置。
比如服务器的端口号设置、监听的IP地址、登录验证方式、验证重试次数等等。具体如下所示:
Port 2222
,而不是使用默认的22作为端口号。ListenAddress host|IPv4_addr:port
,比如配置文件默认的ListenAddress 0.0.0.0
表示监听连接到本机的所有IP地址,即允许能够与本机进行通信的所有IP建立连接。~/.ssh
目录的权限、所有者等信息。默认是yes。10:30:100
(start:rate:full),超过这个值之外的连接会被随机丢弃,比如默认值设置中,如果当前开启了10个未验证连接,那么sshd会随机选择30%(rate/100*100%)进行丢弃。[root@c7u6-ha1 ~]# vim /etc/ssh/sshd_config [root@c7u6-ha1 ~]# vim /root/hello [root@c7u6-ha1 ~]# systemctl restart sshd [root@c7u6-ha1 ~]# ssh localhost The authenticity of host 'localhost (::1)' can't be established. ECDSA key fingerprint is SHA256:Rn2dyaySjkXHSugIk+//fvGGNkdRFTrnLbortO+5FOU. ECDSA key fingerprint is MD5:e5:7d:10:25:0e:51:a1:8b:bb:d1:3a:d8:c1:29:41:3c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts. #------------------------ @@Hello World@@ #------------------------ Last login: Tue Jun 22 08:35:59 2021 from 192.168.122.14 [root@c7u6-ha1 ~]# [root@c7u6-ha1 ~]# cat /etc/ssh/sshd_config | egrep Banner #Banner none Banner /root/hello [root@c7u6-ha1 ~]# cat /root/hello #------------------------ @@Hello World@@ #------------------------ [root@c7u6-ha1 ~]#
上述是一些比较常见的sshd服务的设置参数。更多的服务器相关的参数解释,参见man sshd_config
。
[1]. OpenSSL Certificate Authority
[2]. How to setup your own CA with OpenSSL