创建San证书| openssl用san命令行生成csr

时间:2020-02-23 14:40:11  来源:igfitidea点击:

在本文中,我们将学习使用openssl使用san命令行生成csr和使用使用者替代名称的openssl标志csr创建SAN证书的步骤。

之前我们使用openssl创建服务器和客户端证书。

我们最终遇到了这样的情况:如果我们使用其他服务器名称,则客户端服务器TCP握手会失败。
为了解决这个问题,我们有两种方法

  • 为其他每个IP地址或者主机名创建单独的服务器证书,这可能会很昂贵

  • 创建SAN证书(主题备用名称)

只是为了概括一下我们的练习,前面我们尝试使用IP地址而不是主机名连接到Web服务器时,我们收到了curl:(51)SSL:证书使用者名称'centos8-3'与目标主机名称'10.10.10.17"不匹配。

,因为我们已经使用" centos8-3"作为" client.csr"的通用名称创建了客户证书

[root@centos8-1 tls]# curl --key private/client.key.pem  --cert certs/client.cert.pem --cacert intermediate/certs/ca-chain-bundle.cert.pem  https://10.10.10.17:8443 -v
* Rebuilt URL to: https://10.10.10.17:8443/
*   Trying 10.10.10.17...
* TCP_NODELAY set
* Connected to 10.10.10.17 (10.10.10.17) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: intermediate/certs/ca-chain-bundle.cert.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3/TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=IN; ST=Some-State; L=BANGALORE; O=theitroad; CN=centos8-3
*  start date: Apr  9 01:49:53 2017 GMT
*  expire date: Apr  9 01:49:53 2021 GMT
* SSL: certificate subject name 'centos8-3' does not match target host name '10.10.10.17'
* Closing connection 0
* TLSv1.3 (OUT), TLS alert, [no content] (0):
* TLSv1.3 (OUT), TLS alert, close notify (256):
curl: (51) SSL: certificate subject name 'centos8-3' does not match target host name '10.10.10.17'

什么是SAN证书?

  • ("主题备用名称")SAN证书可以用于多个域名,例如abc.com或者xyz.com,这些域名完全不同,但是它们可以使用相同的证书。

  • SAN可以具有与证书关联的多个通用名称。

  • 当服务器运行多个服务,因此将使用多个名称时,这很有用。

  • 例如,我可以为我的Exchange服务器使用一个SAN证书,其名称为mail.theitroad.comserver.theitroad.com

  • 如果不使用SAN证书,则需要购买多个单一的通用名称证书。

  • 我们定义IP地址和DNS值的列表,当我们使用openssl创建CSR时,这些列表将用作证书验证的通用名。

配置openssl x509扩展名以创建SAN证书

  • 在创建SAN证书之前,我们需要向我们的openssl x509扩展列表中添加更多值。

我们必须使用此外部配置文件,用san命令行用openssl生成csr。

  • 其中我们添加了一个新字段subjectAtlName,键值为@ alt_names

  • 接下来,在alt_names下,我将提供服务器证书在验证客户端请求时应解析的IP地址和DNS名称的完整列表。

  • 因此,使用subjectAltName而不是定义单个公用名,现在我们可以定义我们的服务器证书将对其有效的主机名的完整列表。

[root@centos8-1 certs]# cat server_cert_ext.cnf
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1 = 10.10.10.13
IP.2 = 10.10.10.14
IP.3 = 10.10.10.17
IP.4 = 192.168.43.104
DNS.1 = centos8-3.example.com

生成服务器私钥

如果我们已经有私钥,则可以忽略此步骤。
为了演示起见,我正在创建一个新的服务器私钥。

[root@centos8-1 certs]# openssl genrsa -out server.key.pem 4096                                                                     
Generating RSA private key, 4096 bit long modulus (2 primes)
.................................................++++
..................................................................................................++++
e is 65537 (0x010001)

Openssl使用SAN命令行生成CSR

现在要创建SAN证书,我们必须生成一个新的CSR,即证书签名请求,我们将在下一步中将其与openssl一起使用san命令行生成csr。

[root@centos8-1 certs]# openssl req -new -key server.key.pem -out server.csr                                                        
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]:IN
State or Province Name (full name) []:Karnataka
Locality Name (eg, city) [Default City]:Bengaluru
Organization Name (eg, company) [Default Company Ltd]:R&D
Organizational Unit Name (eg, section) []:theitroad
Common Name (eg, your name or your server's hostname) []:centos8-3
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Openssl签署带有主题备用名称的CSR

  • 接下来使用server.csr使用主题替代名通过-extfile <文件名>对服务器证书进行签名以创建SAN证书

  • 我正在使用上一篇文章中的CA证书链和CA密钥来颁发服务器证书

  • 服务器证书的有效期为365天,并使用sha256算法

  • 由于我们的CA密钥已使用密码加密,因此我使用了-passin来提供密码。
    如果不使用此参数,则命令将提示我们输入密码。

  • 在使用openssl x509的此命令中,我们创建SAN证书server.cert.pem

[root@centos8-1 certs]# openssl x509 -req -in server.csr -passin file:mypass.enc -CA /root/tls/intermediate/certs/ca-chain-bundle.cert.pem -CAkey /root/tls/intermediate/private/intermediate.cakey.pem -out server.cert.pem -CAcreateserial -days 365 -sha256 -extfile server_cert_ext.cnf
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = R&D, OU = theitroad, CN = centos8-3
Getting CA Private Key

OpenSSL验证证书内容

创建SAN证书后,接下来我们可以检查服务器证书的内容,以确保带有主题备用名称的openssl sign CSR成功。

[root@centos8-1 certs]# openssl x509  -noout -text -in server.cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            56:d5:17:9f:23:72:0b:36:5c:e3:be:1f:39:d1:df:48:9b:7e:90:2f
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = IN, ST = Some-State, O = theitroad, CN = centos8-1 Intermediate CA, emailAddress = [email protected]
        Validity
            Not Before: Apr 11 07:45:22 2017 GMT
            Not After : Apr 11 07:45:22 2021 GMT
        Subject: C = IN, ST = Karnataka, L = Bengaluru, O = R&D, OU = theitroad, CN = centos8-3
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (4096 bit)
        <Output trimmed>
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier:
                8F:35:1C:97:4E:2E:E7:E9:EC:FA:FD:BD:97:EB:0A:07:F9:21:98:70
            X509v3 Authority Key Identifier:
                keyid:16:23:DF:95:23:76:04:4E:1D:2D:3E:35:52:0B:BD:8E:28:57:1B:9E
                DirName:/C=IN/ST=Some-State/L=BANGALORE/O=theitroad/CN=centos8-1/[email protected]
                serial:01
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                IP Address:10.10.10.13, IP Address:10.10.10.14, IP Address:10.10.10.17, IP Address:192.168.43.104, DNS:centos8-3.example.com
            <Output trimmed>

如我们所见,我们可以看到我们的使用者替代名称,该名称是我们使用带有opensl的配置文件通过san命令行生成csr所提供的。

安排所有服务器证书以进行客户端身份验证

我们将覆盖Web服务器上一篇文章中的现有服务器证书。
我们正在使用scp将文件从一台服务器复制到另一台服务器,但是我们可以选择任何其他工具来通过网络安全地传输证书

[root@centos8-1 certs]# scp server.key.pem server.cert.pem /root/tls/intermediate/certs/ca-chain-bundle.cert.pem    centos8-3:/etc/httpd/conf.d/certs/
root@centos8-3's password:
server.key.pem                                                                                    100% 3243     4.2MB/s   00:00
server.cert.pem                                                                                   100% 2508     3.5MB/s   00:00
ca-chain-bundle.cert.pem                                                                          100% 4240     5.3MB/s   00:00

接下来重新启动httpd服务以激活更改

[root@centos8-3 ~]# systemctl restart httpd

验证客户端服务器TCP握手

现在,我们将使用openssl generate csr(带有san命令行)提供的主题备用名称中的IP地址之一,使用客户端证书详细信息连接到" centos8-3"上的Web服务器。

[root@centos8-1 certs]# curl --key client.key.pem  --cert client.cert.pem --cacert /root/tls/intermediate/certs/ca-chain-bundle.cert.pem  https://10.10.10.17:8443 -v
* Rebuilt URL to: https://10.10.10.17:8443/
*   Trying 10.10.10.17...
* TCP_NODELAY set
* Connected to 10.10.10.17 (10.10.10.17) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /root/tls/intermediate/certs/ca-chain-bundle.cert.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3/TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=IN; ST=Karnataka; L=Bengaluru; O=R&D; OU=theitroad; CN=centos8-3
*  start date: Apr 11 07:45:22 2017 GMT
*  expire date: Apr 11 07:45:22 2021 GMT
*  subjectAltName: host "10.10.10.17" matched cert's IP address!
*  issuer: C=IN; ST=Some-State; O=theitroad; CN=centos8-1 Intermediate CA; [email protected]
*  SSL certificate verify ok.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET/HTTP/1.1
> Host: 10.10.10.17:8443
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
< Date: Sat, 11 Apr 2017 07:46:16 GMT
< Server: Apache/2.4.37 (centos) OpenSSL/1.1.1c
< Last-Modified: Fri, 31 Jan 2017 17:29:35 GMT
< ETag: "29-59d72ead47e18"
< Accept-Ranges: bytes
< Content-Length: 41
< Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 10.10.10.17 left intact
Welcome at the Ansible managed web server

因此,这次,即使使用IP地址(如我们使用openssl生成带有san命令行的csr)在SAN证书中提供的IP地址,服务器客户端身份验证也成功了。