1 证书生成流程之文字版

1.1 证书签名请求CSR

证书申请者由私钥产生CSR,CSR除了包含公钥,还包含域名,组织等其他相关信息。

1.2 CA

CA收到申请者的CSR后,根据申请者提供的执照等信息进行核对,核对没问题后,对数据(public key + infomation)进行hash计算,比如采用SHA256,生成摘要。 CA用private.key对摘要进行加密,就生成了签名。将签名与数据组合在一起生成证书。

1.3 验证

客户端在tls握手时,收到server发送的CA颁发的证书,然后客户端使用CA的公钥解密server发送的证书中的签名进行解密,得到hash值。 之后client再使用指定的摘要算法对server发送的证书中的数据部分进行hash计算,又得到hash值,比较前后两次生成的hash值是否相同来进行验证。

2 openssl生成证书的流程

2.1 搭建CA

这里基于openssl搭建CA。所以前提条件是已经安装了openssl

1 配置自己的CA认证中心

生成CA的根证书和私钥。根证书中包含CA的公钥。

# vim /etc/pki/tls/openssl.cnf
basicConstraints=CA:TRUE # 让自己成为CA认证中心

2 生成CA的公钥证书和私钥

首先看一下帮助信息:

# /etc/pki/tls/misc/CA -h #查看帮助
usage: /etc/pki/tls/misc/CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify
选项 :
-newcert  新证书
-newreq 新请求
-newreq-nodes 新请求节点
-newca  新的 CA 证书
-sign 签证
-verify 验证

生成CA证书和私钥:

[root@control-plane ~]# /etc/pki/tls/misc/CA -h
usage: /etc/pki/tls/misc/CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify
[root@control-plane ~]# /etc/pki/tls/misc/CA -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 2048 bit RSA private key
...............................................+++
.......+++
writing new private key to '/etc/pki/CA/private/./cakey.pem'
Enter PEM pass phrase:123456
Verifying - Enter PEM pass phrase:123456
-----
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]:haidian
Organization Name (eg, company) [Default Company Ltd]:tux
Organizational Unit Name (eg, section) []:sre
Common Name (eg, your name or your server's hostname) []:tux.github.io
Email Address []:vodaka@126.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:直接回车
An optional company name []:直接回车
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/./cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            a1:2f:00:f9:73:42:b0:04
        Validity
            Not Before: Aug 24 14:31:57 2020 GMT
            Not After : Aug 24 14:31:57 2023 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            organizationName          = tux
            organizationalUnitName    = sre
            commonName                = tux.github.io
            emailAddress              = vodaka@126.com
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                12:14:F9:F0:16:69:8C:B7:01:AF:D1:30:A0:B0:15:81:00:E2:6C:A4
            X509v3 Authority Key Identifier: 
                keyid:12:14:F9:F0:16:69:8C:B7:01:AF:D1:30:A0:B0:15:81:00:E2:6C:A4

            X509v3 Basic Constraints: 
                CA:TRUE
Certificate is to be certified until Aug 24 14:31:57 2023 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated

到此CA认证中心就搭建好了。

3 查看生成的 CA 根证书,根证书中包括 CA 公钥

[root@control-plane ~]# cat /etc/pki/CA/cacert.pem 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            a1:2f:00:f9:73:42:b0:04
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Beijing, O=tux, OU=sre, CN=tux.github.io/emailAddress=vodaka@126.com # CA机构信息
        Validity
            Not Before: Aug 24 14:31:57 2020 GMT
            Not After : Aug 24 14:31:57 2023 GMT
        Subject: C=CN, ST=Beijing, O=tux, OU=sre, CN=tux.github.io/emailAddress=vodaka@126.com
        Subject Public Key Info: # CA公钥信息
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9b:ca:4e:e7:32:00:24:e4:58:2f:9e:d4:d3:d4:
                    78:00:85:4d:72:fa:0c:0d:1a:ce:ae:8f:94:89:dd:
                    68:63:30:04:f8:aa:a8:df:41:0a:90:03:71:3e:fa:
                    c7:b2:f7:f2:9b:7b:df:c0:37:72:d4:4d:2d:d3:a6:
                    3b:22:e8:e0:e7:2b:ae:f3:7e:9c:43:10:6b:8d:b9:
                    9b:4d:9d:c6:09:b6:54:33:02:89:8c:8b:cd:3f:d4:
                    0f:7d:e2:fe:59:fa:19:4a:d1:73:d9:f9:26:ee:09:
                    a9:6f:7c:1e:a3:65:05:ee:65:5c:9c:91:2d:61:22:
                    ca:b7:0b:d0:25:95:cb:d4:26:b1:b2:75:18:ec:8c:
                    db:ff:17:8f:b1:44:10:51:27:33:1d:3c:fc:1b:bd:
                    69:bd:55:df:39:98:21:c5:24:ef:3f:72:e2:10:59:
                    3d:6d:05:5a:3d:95:ca:24:42:69:98:c9:1b:d4:b7:
                    20:13:9e:9a:51:ff:06:74:2e:83:6e:3f:e8:35:24:
                    dc:ba:32:a6:86:ff:26:59:46:1a:08:49:2d:07:db:
                    2f:f8:1c:98:51:ef:2c:b8:f2:cd:02:84:0f:21:f2:
                    c7:62:eb:5c:d5:ea:2f:d1:d5:35:e1:5e:66:18:28:
                    05:c4:22:43:5f:37:6e:7d:b9:f3:59:c6:3b:0c:e9:
                    94:89
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                12:14:F9:F0:16:69:8C:B7:01:AF:D1:30:A0:B0:15:81:00:E2:6C:A4
            X509v3 Authority Key Identifier: 
                keyid:12:14:F9:F0:16:69:8C:B7:01:AF:D1:30:A0:B0:15:81:00:E2:6C:A4

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         23:7a:d7:77:ae:14:4a:b4:26:2a:ed:4a:a3:94:c4:71:8f:cc:
         8c:a9:63:45:97:e3:e6:8f:af:c4:ec:28:c6:c2:9d:fa:51:c5:
         ae:f5:f5:36:53:ee:9f:be:80:36:a4:24:51:ec:5f:32:c7:8d:
         5a:43:0c:f1:8b:32:6e:f8:35:ba:b4:bf:ea:ad:a5:72:73:bf:
         8b:73:4d:d8:1b:74:6c:65:5c:07:0d:01:85:98:bc:43:ca:f0:
         ef:f2:c6:22:9e:90:a9:9b:e6:63:55:cd:61:47:7b:a7:ba:b6:
         f5:0a:e3:ac:af:01:74:43:81:f1:bb:f2:81:87:91:f1:07:86:
         d4:88:14:d9:b6:cf:6b:6c:b6:40:8b:d3:5b:04:7c:db:0f:ff:
         77:3e:60:ee:e8:6a:56:80:99:93:fe:5c:ed:aa:30:9a:af:9c:
         bb:76:cb:74:7f:26:0c:2f:7a:0f:14:02:09:3e:ca:95:7a:3f:
         2c:4e:80:79:f0:06:e0:c8:66:1d:70:07:72:bb:12:39:3d:89:
         86:e4:49:af:79:c6:3d:6e:06:44:de:bc:80:48:6e:f3:6c:b6:
         59:ac:bb:34:3b:eb:8a:a7:5d:df:55:a4:2a:d5:da:64:26:93:
         d5:21:93:f1:61:87:e5:a8:68:b7:23:53:d6:a5:2d:2d:95:a3:
         70:28:8e:21
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIJAKEvAPlzQrAEMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNV
BAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMQwwCgYDVQQKDAN0dXgxDDAKBgNVBAsM
A3NyZTEWMBQGA1UEAwwNdHV4LmdpdGh1Yi5pbzEdMBsGCSqGSIb3DQEJARYOdm9k
YWthQDEyNi5jb20wHhcNMjAwODI0MTQzMTU3WhcNMjMwODI0MTQzMTU3WjByMQsw
CQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamluZzEMMAoGA1UECgwDdHV4MQwwCgYD
VQQLDANzcmUxFjAUBgNVBAMMDXR1eC5naXRodWIuaW8xHTAbBgkqhkiG9w0BCQEW
DnZvZGFrYUAxMjYuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
m8pO5zIAJORYL57U09R4AIVNcvoMDRrOro+Uid1oYzAE+Kqo30EKkANxPvrHsvfy
m3vfwDdy1E0t06Y7Iujg5yuu836cQxBrjbmbTZ3GCbZUMwKJjIvNP9QPfeL+WfoZ
StFz2fkm7gmpb3weo2UF7mVcnJEtYSLKtwvQJZXL1CaxsnUY7Izb/xePsUQQUScz
HTz8G71pvVXfOZghxSTvP3LiEFk9bQVaPZXKJEJpmMkb1LcgE56aUf8GdC6Dbj/o
NSTcujKmhv8mWUYaCEktB9sv+ByYUe8suPLNAoQPIfLHYutc1eov0dU14V5mGCgF
xCJDXzdufbnzWcY7DOmUiQIDAQABo1AwTjAdBgNVHQ4EFgQUEhT58BZpjLcBr9Ew
oLAVgQDibKQwHwYDVR0jBBgwFoAUEhT58BZpjLcBr9EwoLAVgQDibKQwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAI3rXd64USrQmKu1Ko5TEcY/MjKlj
RZfj5o+vxOwoxsKd+lHFrvX1NlPun76ANqQkUexfMseNWkMM8Ysybvg1urS/6q2l
cnO/i3NN2Bt0bGVcBw0BhZi8Q8rw7/LGIp6QqZvmY1XNYUd7p7q29QrjrK8BdEOB
8bvygYeR8QeG1IgU2bbPa2y2QIvTWwR82w//dz5g7uhqVoCZk/5c7aowmq+cu3bL
dH8mDC96DxQCCT7KlXo/LE6AefAG4MhmHXAHcrsSOT2JhuRJr3nGPW4GRN68gEhu
82y2Way7NDvriqdd31WkKtXaZCaT1SGT8WGH5ahotyNT1qUtLZWjcCiOIQ==
-----END CERTIFICATE-----

4 查看根证书私钥

[root@control-plane ~]# cat /etc/pki/CA/private/cakey.pem 
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIe1QeUe984l4CAggA
MBQGCCqGSIb3DQMHBAiSFfkPdZdzeASCBMjmmYacx5Wun9dF6qMF5AurOjGvP1X4
qUMwi+J7xlV9L02vXNLcemvCGZT8PY8xCEw1KpFsyNk3GrpruO7Gtwt/y9cpEQJ4
tovWKiob9mP8TEPKolaz9NXR38xBk6paR+rOQx/rQUFcal8vg4E1cShmELFNwLyQ
izHSPsbdcYj9eGIHTvpR08PlZa7yJ3Rl4Ox1GZCuWgLGEplj0mcg5NX4K0Yp0ZUM
oyfqzeCprFjAbLCMNh3ikos41tZU1l67a2WhzWlUF1tjScRxBjKwfL03rkFLyWLW
VK8WnvIYHXO1rnfrvhIGGnR95kSabT2ZkilllU5hQ3DlW5o8Qpnm8i0bO6b99Qu6
Jw/+5fg1HBiGCfstuPFEBBa6MiODIqY+yeaW/1Z6GY+wWjL+4yA0ZPVpkZrtquu7
kTRqNfI8cnbC1k5mgQD01HPB1k4JaYvQI3LqK2s77Ez6hzOzemfLdIH7TOf+tGe0
dz9FVBk1pDhiBFbjqfOKbFS33/Uq4g6IHVyih/IBKXznJ8ogl0GJdkA1uVPUsrQU
dVHuI6tIPaZGejv5mBSkdn+DuWxXKnK3cYlAIEenaGuo4XIbLVkEfz2ITPubFFJx
m9bRSOdAG4H3wIDTYdXxqOgAsY2aWd9kjz8kAxUAR4cfTsBDrtosuFbz83XWjdBy
4RrlgzKy7VkHpD2M0NTzwZ4sScgTcWSZa44P9+acZzZuBCmqV0E+V/btJKUEuAqp
ymQdIg+l1UcCimmMShHmAznxMFrS8daSXNEEdaTwLA/YWT3NcWgAkNx1VK5AkX9W
Gs3/1fDxcIAOZViKtBKCI0lc/xenRoKSXzfiQosKHop+Zu2KrQFUoyAD7PKinkkb
hBiLwWV6WXWwcc0S8IgyDsqfZUco2v3yu59aBx1bFkR9mhawoGKukiDvewiPGNBq
5es8DFm5VfbxvXQafe8WdJY+du6QOzHthQJgJvjHfRFuHt6ol2Jzo/yAqPiVJMa7
vhTnU1jWTVDR6d6G4kMvr40av0qyLfo+uI54b67gtZBRAP2N84u/Hf8iUoLVe7zn
SaXNTtBpnm9OYsUIeeP5rq4FkyMoGYBFUiw+SAae/tmOCLWVuPtpCYEUq4ZZySbL
qZ0wHvimxXMZOkd1bwPlB/qqV+Ac2SPPcyZ2MH2EIgjZ4oqb1Ey0IUjOzJGffxnM
kwiOLQddhtAWfOAFvGLMJ8n5OuzduYwwMk2CBvFgBnCk16Tc0T1FdlVo8UMvWMK0
/ugjEd8pu3ahyROdRfGvDe6azmlSmrtp+GWwYtdtWNhY2Uy1CFdneWb/suHP4T0A
mKbmSVQNELlzmDcOCtAquWf3YvKaTUmx8q1BDrz4sNcY7ZYeNa2Ve3Z5xdE2+CPc
SCNYusFiDtrXXV7OcY2qkTJr3oAz6ihiGhhkQzO2gitrrQ5u3YaBMlsPPFe6wbHr
wmUxeruW9sILAHj75yk4n3Kq9N+6RBsEhTt/tc/WZxC9tpqI6N7jAb+8fF47QCRN
UIWhmIu1Gq6PR6Gt4GjsZAJKtJiDvCKNPam3jZvcpEB9SgCBW3hA0cB8HJBn009t
11wDpDFQ32NX8w+ph8GYW34u6f7MkSUELncUrZcMtLIFs/FNKqWVQqMd/LieRkFQ
ZVU=
-----END ENCRYPTED PRIVATE KEY-----

2.2 生成example.com网站的CSR

首先生成私钥,由私钥可产生公钥,但是不能由公钥反向生成私钥。私钥应该在提供web服务的服务器上生成,这里出于演示目的,将私钥生成在CA服务器的/root/example.com目录下

首先查看帮助信息:

[root@control-plane ~]# openssl genrsa -h
usage: genrsa [args] [numbits]
 -des            encrypt the generated key with DES in cbc mode
 -des3           encrypt the generated key with DES in ede cbc mode (168 bit key)
 -idea           encrypt the generated key with IDEA in cbc mode
 -seed
                 encrypt PEM output with cbc seed
 -aes128, -aes192, -aes256
                 encrypt PEM output with cbc aes
 -camellia128, -camellia192, -camellia256
                 encrypt PEM output with cbc camellia
 -out file       output the key to 'file
 -passout arg    output file pass phrase source
 -f4             use F4 (0x10001) for the E value
 -3              use 3 for the E value
 -engine e       use engine e, possibly a hardware device.
 -rand file:file:...
                 load the file (or the files in the directory) into
                 the random number generator
···

生成私钥

```bash
[root@control-plane ~]# openssl genrsa -des3 -out example.com/server.key
Generating RSA private key, 2048 bit long modulus
......................+++
...............+++
e is 65537 (0x10001)
Enter pass phrase for example.com/server.key:123456
Verifying - Enter pass phrase for example.com/server.key:123456
···

使用私钥生成CSR文件:

先查看帮助信息:

```bash
[root@control-plane ~]# openssl req -h
unknown option -h
req [options] <infile >outfile
where options  are
 -inform arg    input format - DER or PEM
 -outform arg   output format - DER or PEM
 -in arg        input file
 -out arg       output file
 -text          text form of request
 -pubkey        output public key
 -noout         do not output REQ
 -verify        verify signature on REQ
 -modulus       RSA modulus
 -nodes         don't encrypt the output key
 -engine e      use engine e, possibly a hardware device
 -subject       output the request's subject
 -passin        private key password source
 -key file      use the private key contained in file
 -keyform arg   key file format
 -keyout arg    file to send the key to
 -rand file:file:...
                load the file (or the files in the directory) into
                the random number generator
 -newkey rsa:bits generate a new RSA key of 'bits' in size
 -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'
 -newkey ec:file generate a new EC key, parameters taken from CA in 'file'
 -[digest]      Digest to sign with (see openssl dgst -h for list)
 -config file   request template file.
 -subj arg      set or modify request subject
 -multivalue-rdn enable support for multivalued RDNs
 -new           new request.
 -batch         do not ask anything during request generation
 -x509          output a x509 structure instead of a cert. req.
 -days          number of days a certificate generated by -x509 is valid for.
 -set_serial    serial number to use for a certificate generated by -x509.
 -newhdr        output "NEW" in the header lines
 -asn1-kludge   Output the 'request' in a format that is wrong but some CA's
                have been reported as requiring
 -extensions .. specify certificate extension section (override value in config file)
 -reqexts ..    specify request extension section (override value in config file)
 -utf8          input characters are UTF8 (default ASCII)
 -nameopt arg    - various certificate name options
 -reqopt arg    - various request text options

生成签名请求:

[root@control-plane ~]# openssl req -new -key /root/example.com/server.key -out /root/example.com/server.csr
Enter pass phrase for /root/example.com/server.key:
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 # 与CA一致否则会
State or Province Name (full name) []:Beijing
Locality Name (eg, city) [Default City]:haidian
Organization Name (eg, company) [Default Company Ltd]:tux
Organizational Unit Name (eg, section) []:sre
Common Name (eg, your name or your server's hostname) []:example.com #通过浏览器访问的域名,也可以使用IP
Email Address []:example@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:直接回车
An optional company name []:直接回车

将CSR文件发给CA服务器,这里因为是演示,所以在同一台服务器上,因此直接是CA进行签名:

首先查看帮助

[root@control-plane ~]# openssl ca -h
unknown option -h
usage: ca args

 -verbose        - Talk alot while doing things
 -config file    - A config file
 -name arg       - The particular CA definition to use
 -gencrl         - Generate a new CRL
 -crldays days   - Days is when the next CRL is due
 -crlhours hours - Hours is when the next CRL is due
 -startdate YYMMDDHHMMSSZ  - certificate validity notBefore
 -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)
 -days arg       - number of days to certify the certificate for
 -md arg         - md to use, see openssl dgst -h for list
 -policy arg     - The CA 'policy' to support
 -keyfile arg    - private key file
 -keyform arg    - private key file format (PEM or ENGINE)
 -key arg        - key to decode the private key if it is encrypted
 -cert file      - The CA certificate
 -selfsign       - sign a certificate with the key associated with it
 -in file        - The input PEM encoded certificate request(s)
 -out file       - Where to put the output file(s)
 -outdir dir     - Where to put output certificates
 -infiles ....   - The last argument, requests to process
 -spkac file     - File contains DN and signed public key and challenge
 -ss_cert file   - File contains a self signed cert to sign
 -preserveDN     - Don't re-order the DN
 -noemailDN      - Don't add the EMAIL field into certificate' subject
 -batch          - Don't ask questions
 -msie_hack      - msie modifications to handle all those universal strings
 -revoke file    - Revoke a certificate (given in file)
 -subj arg       - Use arg instead of request's subject
 -utf8           - input characters are UTF8 (default ASCII)
 -multivalue-rdn - enable support for multivalued RDNs
 -extensions ..  - Extension section (override value in config file)
 -extfile file   - Configuration file with X509v3 extentions to add
 -crlexts ..     - CRL extension section (override value in config file)
 -engine e       - use engine e, possibly a hardware device.
 -status serial  - Shows certificate status given the serial number
 -updatedb       - Updates db for expired certificates

进行签名:

[root@control-plane ~]# openssl ca -keyfile /etc/pki/CA/private/cakey.pem -cert /etc/pki/CA/cacert.pem -in /root/example.com/server.csr -out /root/example.com/server.crt
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
The organizationName field needed to be the same in the
CA certificate (tux) and the request (example)

上面提示organizationName字段,需要csr文件与CA中的保持一致,所以需要修改csr文件的organizationName字段为tux,然后进行签名:

[root@control-plane ~]# openssl ca -keyfile /etc/pki/CA/private/cakey.pem -cert /etc/pki/CA/cacert.pem -in /root/example.com/server.csr -out /root/example.com/server.crt
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:123456
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            a1:2f:00:f9:73:42:b0:05
        Validity
            Not Before: Aug 24 15:48:26 2020 GMT
            Not After : Aug 24 15:48:26 2021 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Beijing
            organizationName          = tux
            organizationalUnitName    = sre
            commonName                = example.com
            emailAddress              = example@example.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:TRUE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                F8:B8:58:A7:41:86:0D:E2:FB:1E:FC:A8:42:3D:F8:72:0E:93:B6:FD
            X509v3 Authority Key Identifier: 
                keyid:12:14:F9:F0:16:69:8C:B7:01:AF:D1:30:A0:B0:15:81:00:E2:6C:A4

Certificate is to be certified until Aug 24 15:48:26 2021 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

之后将证书发送给申请者,网站部署证书后就可以使用了。但需要客户端浏览器根据提示导入证书。