最新、最全、最好的自签名证书教程(开箱即用)

虽然我们不经常创建证书(尤其是根证书,申请 HTTPS 证书还是挺常见的), 但是偶尔我们还是需要创建特殊的自签名证书以便 开发/测试 使用, 最常见的就是需要 localhost 证书。

对于需要 mTLS 认证的场景来说,我们至少需要创建 3 个证书 以及 3 个公私密钥对。 分别是: 根证书、服务器端证书、客户端证书。

注解

本教程不涉及多级证书。

现在就让我们开始一步一步的创建属于自己的自签名证书吧:

准备文件目录结构

警告

请创建一个空目录(文件夹)来实验此教程。

使用如下命令初始化文件夹:

rm -rf certs csr newcerts pkcs12 private index* serial*
mkdir certs
mkdir csr
mkdir newcerts
mkdir pkcs12
mkdir private
echo "1000" > serial
touch index.txt

创建根证书

这是教您如何使用 openssl 创建自签名根证书的流程。

创建根密钥

$ openssl genrsa -out private/ca.key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....++
.........++
e is 65537 (0x10001)

我们在这儿使用 RSA 4096, 因为根证书不经常使用,为了更好的安全性,我们使用较大的参数。

注解

生产环境一般都会有中间证书,我们这儿为了方便省略了中间证书的签发流程

创建根证书

现在我们使用刚创建的根密钥来创建我们的根证书:

$ openssl req -config openssl.ini -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem -subj '/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN'

重要

建议您要使用 X509v3 扩展。

注解

openssl.ini 的配置在本文最后。

实际使用中请酌情填写有效期 或 咨询密码学专家的建议。

查看根证书

查看我们刚刚创建的根证书:

警告

请确保有 X509v3 扩展

$ openssl x509 -noout -text -in certs/ca.cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 17833865128296389378 (0xf77e9dd8a8551b02)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Sep 13 08:26:41 2021 GMT
            Not After : Sep  8 08:26:41 2041 GMT
        Subject: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:c8:b4:d7:f7:d1:92:4b:c2:f9:18:a0:36:fc:04:
                    3f:22:33:90:d1:f2:a8:05:d4:8e:eb:0a:9a:30:bf:
                    88:9a:dd:d3:aa:a4:f4:d0:e5:30:02:ed:5d:55:09:
                    c1:3a:4c:ce:cf:96:59:21:86:f9:e3:12:8f:b0:1e:
                    29:42:ff:97:e0:df:39:5b:ae:b5:bc:33:b2:1f:a4:
                    e2:87:0e:26:28:d9:8f:e9:79:1b:39:69:fa:22:71:
                    0b:0b:6a:5f:98:37:e4:2f:95:a1:4f:6f:83:f5:43:
                    1e:18:c3:3a:39:f9:34:cf:cc:9c:ff:0c:d8:8d:c6:
                    50:ca:d6:c9:1a:2e:66:d2:9b:90:e3:88:82:7c:23:
                    f0:a5:df:e7:47:74:b9:3b:c7:44:44:ec:2b:3d:a5:
                    ab:0a:c2:ba:9f:3a:f5:f5:4c:0e:56:5c:98:27:d9:
                    3f:8a:c3:a2:8b:84:c9:cf:f2:0d:5c:ce:d3:9b:c9:
                    c9:58:24:d9:2f:50:41:04:b2:12:16:37:63:46:7c:
                    50:41:46:03:aa:55:11:2a:5e:b7:27:ad:7e:1e:01:
                    d3:37:e9:88:3a:eb:06:ad:8e:9f:fa:79:77:c7:e6:
                    52:41:ee:a8:ca:4c:df:2f:17:cf:a0:05:ed:d5:f3:
                    01:52:41:27:37:58:3a:f6:0e:d1:fe:0e:28:71:0f:
                    c9:77:17:76:fd:ef:48:ed:97:04:8e:ec:df:fa:dc:
                    27:2b:fe:2f:55:d3:c9:2d:6e:11:44:03:65:43:3e:
                    a3:8d:7a:57:95:fb:4f:19:9a:a1:40:ff:86:7b:d9:
                    c4:26:fc:76:f8:8f:b3:34:c5:6d:1f:96:ef:1b:b3:
                    4e:4f:8d:55:6f:af:82:cf:62:e3:91:c0:42:6f:3e:
                    81:ed:62:f2:05:f3:ea:32:e2:e5:4b:68:1f:f2:52:
                    64:6d:8d:ef:1b:a8:32:8d:aa:31:3e:a8:66:3f:4b:
                    0b:f3:b1:18:57:5f:5a:72:26:02:ea:b3:98:72:6a:
                    ff:9f:c2:90:c0:82:93:a7:36:a3:dd:79:60:99:1a:
                    2b:a5:a4:39:d6:45:3c:74:f2:0e:02:34:3e:80:7e:
                    40:b1:17:b7:68:70:50:b6:6e:48:ea:53:63:8a:0d:
                    06:22:35:65:cc:7e:74:27:d1:5d:7a:c8:21:de:31:
                    e2:cd:42:f5:fd:46:13:95:bd:4c:e3:23:18:ae:79:
                    72:f9:50:72:66:2e:41:12:08:92:44:d7:11:e7:56:
                    42:1d:63:c7:ff:9f:94:2d:2d:e1:96:39:42:28:b3:
                    f9:cd:7e:f3:60:97:f5:f4:ea:6d:93:fe:d5:33:80:
                    df:93:17:9e:b9:d2:40:c6:eb:ba:e6:78:c6:6c:66:
                    5b:98:79
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:127.0.0.1, DNS:::1
    Signature Algorithm: sha256WithRSAEncryption
         04:cf:4f:77:a2:7f:31:8e:72:d0:cb:cf:f7:90:71:24:86:a8:
         b5:e2:da:45:11:c0:29:a6:d6:84:42:aa:2a:f9:8e:5e:bd:16:
         00:68:a5:a1:14:d6:1b:48:9c:4d:b2:4e:90:4c:e0:3d:6a:a6:
         54:1e:51:58:f1:10:68:a3:2a:49:33:b4:54:8f:86:1c:ca:61:
         1f:3f:ef:2e:7b:72:5f:75:96:f0:3a:36:47:75:bc:db:37:1f:
         22:b5:06:05:ab:e5:b5:3e:ac:8d:51:51:52:8e:88:4e:bb:d2:
         2a:77:00:ed:b7:a7:c4:f0:4a:f9:4a:b9:48:80:e4:20:a4:3c:
         75:33:ec:68:7e:51:b0:c4:c1:89:64:b3:ab:6f:b2:31:01:ca:
         4f:69:44:7d:c0:d7:f9:1b:ec:4a:88:57:5e:e4:23:d6:3c:b8:
         b2:5f:d0:18:ac:c7:31:79:6c:d0:93:32:5b:53:87:7d:8b:7d:
         35:44:7c:39:63:85:a6:a2:6b:1a:8d:23:e4:a2:6a:d7:71:40:
         c6:23:76:8d:78:2f:b3:3c:f9:18:2b:40:fd:3e:14:4f:87:9c:
         44:67:17:69:e3:27:5a:b6:f2:bd:0b:19:d0:db:bf:dd:82:a5:
         27:34:0b:aa:7c:7c:4f:99:23:85:5c:2d:6f:25:c4:36:ae:28:
         e8:8a:43:e6:8f:b1:4b:59:64:00:09:57:3e:6f:11:31:7e:ed:
         3e:57:e0:37:d3:2e:a2:a6:15:9b:06:03:94:aa:72:06:e6:31:
         20:2c:0b:fe:0c:51:65:e3:5c:ec:8f:a2:c0:4a:e2:9d:0b:a9:
         d0:26:0d:64:51:63:31:9c:ce:81:7f:9c:8e:88:f2:e9:b8:57:
         05:af:6c:54:e7:92:5a:6e:7f:24:3d:5e:65:3c:9e:cf:1a:41:
         cd:72:bb:52:f4:4f:4b:10:49:25:fe:74:90:a9:29:98:42:78:
         f0:9e:13:12:a8:97:6e:96:07:90:90:b6:2f:fd:34:71:de:97:
         1b:2d:46:3c:c2:cc:36:2e:43:75:65:a6:70:8e:97:f9:07:27:
         8e:41:b6:10:a2:b9:ed:e3:bc:45:34:a0:35:55:4c:54:c5:ff:
         cd:7b:07:ad:05:e1:a8:29:7f:29:fe:85:17:46:ad:40:fc:1f:
         73:2a:c5:5b:27:14:62:8b:fa:84:ca:30:08:06:8e:80:ce:f6:
         78:7d:c1:a7:b9:24:bb:30:0e:b1:f6:9b:55:bc:ae:8f:0e:75:
         1b:e5:9b:22:68:d1:b8:71:74:b0:52:e0:1a:ed:57:17:7e:c3:
         ba:bb:84:ab:2a:f2:1d:57:db:fb:f6:45:32:bd:44:58:23:a6:
         13:3e:43:0d:41:35:05:19

创建服务器证书

现在让我们使用上面创建的根证书,创建一个我们可以使用的 localhost 的 https 证书。

创建服务器密钥

$ openssl genrsa -out private/localhost.key.pem 2048
Generating RSA private key, 2048 bit long modulus
.....................+++
......................................................................................................................................................+++
e is 65537 (0x10001)

注解

我们使用 2048 位的 RSA 证书是因为服务器证书会经常使用,这样可以降低CPU的压力,而且并不影响安全性。

生成服务器端证书请求文件

请求文件中的 国家、省份 最好跟 根证书的保持一致(这样可以保证最大的兼容性)。

注解

这里也就是通常说的生成 CSR 文件

$ openssl req -config openssl.ini -key private/localhost.key.pem -new -sha256 -reqexts req_ext -out csr/localhost.csr.pem -subj '/CN=localhost/O=QiYuTech/ST=BeiJing/C=CN'

查看服务器端请求文件

$ openssl x509 -noout -text -in certs/ca.cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 17833865128296389378 (0xf77e9dd8a8551b02)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Sep 13 08:26:41 2021 GMT
            Not After : Sep  8 08:26:41 2041 GMT
        Subject: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:c8:b4:d7:f7:d1:92:4b:c2:f9:18:a0:36:fc:04:
                    3f:22:33:90:d1:f2:a8:05:d4:8e:eb:0a:9a:30:bf:
                    88:9a:dd:d3:aa:a4:f4:d0:e5:30:02:ed:5d:55:09:
                    c1:3a:4c:ce:cf:96:59:21:86:f9:e3:12:8f:b0:1e:
                    29:42:ff:97:e0:df:39:5b:ae:b5:bc:33:b2:1f:a4:
                    e2:87:0e:26:28:d9:8f:e9:79:1b:39:69:fa:22:71:
                    0b:0b:6a:5f:98:37:e4:2f:95:a1:4f:6f:83:f5:43:
                    1e:18:c3:3a:39:f9:34:cf:cc:9c:ff:0c:d8:8d:c6:
                    50:ca:d6:c9:1a:2e:66:d2:9b:90:e3:88:82:7c:23:
                    f0:a5:df:e7:47:74:b9:3b:c7:44:44:ec:2b:3d:a5:
                    ab:0a:c2:ba:9f:3a:f5:f5:4c:0e:56:5c:98:27:d9:
                    3f:8a:c3:a2:8b:84:c9:cf:f2:0d:5c:ce:d3:9b:c9:
                    c9:58:24:d9:2f:50:41:04:b2:12:16:37:63:46:7c:
                    50:41:46:03:aa:55:11:2a:5e:b7:27:ad:7e:1e:01:
                    d3:37:e9:88:3a:eb:06:ad:8e:9f:fa:79:77:c7:e6:
                    52:41:ee:a8:ca:4c:df:2f:17:cf:a0:05:ed:d5:f3:
                    01:52:41:27:37:58:3a:f6:0e:d1:fe:0e:28:71:0f:
                    c9:77:17:76:fd:ef:48:ed:97:04:8e:ec:df:fa:dc:
                    27:2b:fe:2f:55:d3:c9:2d:6e:11:44:03:65:43:3e:
                    a3:8d:7a:57:95:fb:4f:19:9a:a1:40:ff:86:7b:d9:
                    c4:26:fc:76:f8:8f:b3:34:c5:6d:1f:96:ef:1b:b3:
                    4e:4f:8d:55:6f:af:82:cf:62:e3:91:c0:42:6f:3e:
                    81:ed:62:f2:05:f3:ea:32:e2:e5:4b:68:1f:f2:52:
                    64:6d:8d:ef:1b:a8:32:8d:aa:31:3e:a8:66:3f:4b:
                    0b:f3:b1:18:57:5f:5a:72:26:02:ea:b3:98:72:6a:
                    ff:9f:c2:90:c0:82:93:a7:36:a3:dd:79:60:99:1a:
                    2b:a5:a4:39:d6:45:3c:74:f2:0e:02:34:3e:80:7e:
                    40:b1:17:b7:68:70:50:b6:6e:48:ea:53:63:8a:0d:
                    06:22:35:65:cc:7e:74:27:d1:5d:7a:c8:21:de:31:
                    e2:cd:42:f5:fd:46:13:95:bd:4c:e3:23:18:ae:79:
                    72:f9:50:72:66:2e:41:12:08:92:44:d7:11:e7:56:
                    42:1d:63:c7:ff:9f:94:2d:2d:e1:96:39:42:28:b3:
                    f9:cd:7e:f3:60:97:f5:f4:ea:6d:93:fe:d5:33:80:
                    df:93:17:9e:b9:d2:40:c6:eb:ba:e6:78:c6:6c:66:
                    5b:98:79
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:127.0.0.1, DNS:::1
    Signature Algorithm: sha256WithRSAEncryption
         04:cf:4f:77:a2:7f:31:8e:72:d0:cb:cf:f7:90:71:24:86:a8:
         b5:e2:da:45:11:c0:29:a6:d6:84:42:aa:2a:f9:8e:5e:bd:16:
         00:68:a5:a1:14:d6:1b:48:9c:4d:b2:4e:90:4c:e0:3d:6a:a6:
         54:1e:51:58:f1:10:68:a3:2a:49:33:b4:54:8f:86:1c:ca:61:
         1f:3f:ef:2e:7b:72:5f:75:96:f0:3a:36:47:75:bc:db:37:1f:
         22:b5:06:05:ab:e5:b5:3e:ac:8d:51:51:52:8e:88:4e:bb:d2:
         2a:77:00:ed:b7:a7:c4:f0:4a:f9:4a:b9:48:80:e4:20:a4:3c:
         75:33:ec:68:7e:51:b0:c4:c1:89:64:b3:ab:6f:b2:31:01:ca:
         4f:69:44:7d:c0:d7:f9:1b:ec:4a:88:57:5e:e4:23:d6:3c:b8:
         b2:5f:d0:18:ac:c7:31:79:6c:d0:93:32:5b:53:87:7d:8b:7d:
         35:44:7c:39:63:85:a6:a2:6b:1a:8d:23:e4:a2:6a:d7:71:40:
         c6:23:76:8d:78:2f:b3:3c:f9:18:2b:40:fd:3e:14:4f:87:9c:
         44:67:17:69:e3:27:5a:b6:f2:bd:0b:19:d0:db:bf:dd:82:a5:
         27:34:0b:aa:7c:7c:4f:99:23:85:5c:2d:6f:25:c4:36:ae:28:
         e8:8a:43:e6:8f:b1:4b:59:64:00:09:57:3e:6f:11:31:7e:ed:
         3e:57:e0:37:d3:2e:a2:a6:15:9b:06:03:94:aa:72:06:e6:31:
         20:2c:0b:fe:0c:51:65:e3:5c:ec:8f:a2:c0:4a:e2:9d:0b:a9:
         d0:26:0d:64:51:63:31:9c:ce:81:7f:9c:8e:88:f2:e9:b8:57:
         05:af:6c:54:e7:92:5a:6e:7f:24:3d:5e:65:3c:9e:cf:1a:41:
         cd:72:bb:52:f4:4f:4b:10:49:25:fe:74:90:a9:29:98:42:78:
         f0:9e:13:12:a8:97:6e:96:07:90:90:b6:2f:fd:34:71:de:97:
         1b:2d:46:3c:c2:cc:36:2e:43:75:65:a6:70:8e:97:f9:07:27:
         8e:41:b6:10:a2:b9:ed:e3:bc:45:34:a0:35:55:4c:54:c5:ff:
         cd:7b:07:ad:05:e1:a8:29:7f:29:fe:85:17:46:ad:40:fc:1f:
         73:2a:c5:5b:27:14:62:8b:fa:84:ca:30:08:06:8e:80:ce:f6:
         78:7d:c1:a7:b9:24:bb:30:0e:b1:f6:9b:55:bc:ae:8f:0e:75:
         1b:e5:9b:22:68:d1:b8:71:74:b0:52:e0:1a:ed:57:17:7e:c3:
         ba:bb:84:ab:2a:f2:1d:57:db:fb:f6:45:32:bd:44:58:23:a6:
         13:3e:43:0d:41:35:05:19

重要

一定要确保生成的CSR文件中包含如下信息, 否则可能 https://localhost 访问可能现实证书错误。

X509v3 Subject Alternative Name:

DNS:localhost, DNS:127.0.0.1, DNS:::1

警告

很多人生成的证书无法使用通常都是因为没有附带 X590v3 的扩展字段。

比如说: 你要是想通过 https 访问 localhost https://localhost, 在 CSR 请求中确保有 DNS:localhost 字段

生成服务器端证书

$ openssl ca -batch -config openssl.ini -extensions server_cert -days 375 -notext -md sha256 -in csr/localhost.csr.pem -out certs/localhost.cert.pem
Using configuration from openssl.ini
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4096 (0x1000)
        Validity
            Not Before: Sep 13 08:26:42 2021 GMT
            Not After : Sep 23 08:26:42 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BeiJing
            organizationName          = QiYuTech
            commonName                = localhost
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                QiYuTech Server Certificate
            X509v3 Subject Key Identifier: 
                85:07:20:8D:67:34:23:42:F4:84:AD:29:BF:FF:4A:9C:6A:FA:CF:14
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:F7:7E:9D:D8:A8:55:1B:02

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:127.0.0.1, DNS:::1
Certificate is to be certified until Sep 23 08:26:42 2022 GMT (375 days)

Write out database with 1 new entries
Data Base Updated

注解

实际就是使用根证书对服务器证书签名

查看服务器端证书

$ openssl x509 -noout -text -in certs/localhost.cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4096 (0x1000)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Sep 13 08:26:42 2021 GMT
            Not After : Sep 23 08:26:42 2022 GMT
        Subject: C=CN, ST=BeiJing, O=QiYuTech, CN=localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a8:13:6e:02:45:21:ad:f7:b2:da:a1:07:ad:92:
                    8b:45:b6:bb:fe:5c:27:38:a7:73:ee:09:d7:db:0d:
                    c9:7e:c1:d1:3d:dd:61:7f:b4:cb:a9:93:1a:25:b9:
                    06:d9:8c:63:e6:a4:9a:cd:2f:39:93:cf:79:a4:6a:
                    8b:b8:af:fc:70:d1:d9:2c:91:d1:19:1a:eb:91:bf:
                    ac:0a:81:d9:51:30:5e:d3:96:00:0c:d0:02:d6:99:
                    11:df:02:ab:76:64:47:ca:78:75:0d:11:8b:f0:ea:
                    13:76:a7:50:8f:e4:41:b2:c4:9b:e5:a4:c0:71:07:
                    46:fe:92:49:60:90:a7:25:f5:e0:ce:91:c8:bf:1c:
                    3c:a5:b0:ad:d4:99:11:e4:0b:bb:4e:24:a8:36:c6:
                    de:b5:b5:e3:8c:bc:71:38:55:46:c0:73:a0:52:48:
                    bf:f0:54:1e:ac:3d:93:8e:06:66:4d:2d:62:15:c5:
                    4f:f0:c6:cb:7a:30:ef:91:9a:2c:7a:55:38:0f:59:
                    18:d6:e3:a6:5d:60:01:db:c5:55:70:ff:a6:87:38:
                    ec:90:c4:19:c9:27:10:43:8b:43:9f:e7:d6:9d:6e:
                    67:68:bc:d1:75:87:5d:53:39:26:00:3e:27:a5:82:
                    37:7a:d3:1b:59:ef:a1:20:f3:a8:6c:df:5a:47:01:
                    5b:79
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                QiYuTech Server Certificate
            X509v3 Subject Key Identifier: 
                85:07:20:8D:67:34:23:42:F4:84:AD:29:BF:FF:4A:9C:6A:FA:CF:14
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:F7:7E:9D:D8:A8:55:1B:02

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:127.0.0.1, DNS:::1
    Signature Algorithm: sha256WithRSAEncryption
         b4:0b:11:3e:85:71:93:16:91:26:05:63:b8:47:80:47:42:f1:
         2e:1d:0c:6f:6a:15:98:88:e6:12:11:ba:17:89:54:ba:51:c5:
         f1:c5:40:17:b1:ef:2f:1e:4a:e5:04:da:60:d7:26:f0:35:71:
         15:ac:47:25:44:01:8f:79:d5:10:f7:77:24:c4:54:d5:29:73:
         8b:8b:21:2d:f7:0e:3e:41:88:cd:25:7f:3e:ba:62:ce:ab:e7:
         ea:76:ed:a3:86:9b:1b:83:d1:ee:d4:85:b0:cd:c8:a0:f0:89:
         7f:2a:d5:5e:84:b9:43:a3:e1:7a:6f:ee:c7:26:b9:9b:03:27:
         15:5b:d0:ef:31:bb:bc:8d:a8:40:0f:94:4c:1e:03:0b:40:f6:
         c8:75:7f:28:3d:89:5f:c6:3b:02:a4:d2:7f:ac:d3:53:b1:83:
         73:d6:d8:9c:c9:06:c6:29:fe:07:a3:44:15:1f:2f:52:c0:56:
         56:dd:8d:4c:c6:f8:75:ec:22:88:91:fa:e8:bd:1d:7f:c5:a9:
         4c:a4:63:ac:18:79:13:63:45:44:d2:3c:e0:2a:66:0d:21:51:
         26:bd:e1:3d:64:94:6d:e3:9f:f0:7f:2a:5d:ac:14:99:28:bc:
         5b:97:9a:43:54:e9:33:95:fc:cf:7d:c8:cb:19:ad:ba:04:15:
         f4:39:fc:71:19:1b:18:56:f2:db:de:98:b5:64:fd:85:ff:3b:
         60:11:7f:4b:fa:a5:34:6a:a6:d8:b7:2e:97:ce:7f:bc:cf:8d:
         44:22:e2:cd:a5:20:4b:6d:dc:0b:77:08:fd:eb:16:5e:f7:49:
         88:84:e9:63:e1:c5:8a:bf:04:81:ca:8f:c3:75:01:a8:7a:fe:
         92:4b:b4:38:c2:89:17:d8:c5:a3:88:ae:fd:41:18:24:5f:85:
         25:12:ac:c6:1a:2c:a4:67:f4:8f:d1:86:fe:d9:d9:0b:db:0c:
         3e:7d:87:36:0c:b4:2a:04:30:e6:ae:c8:f4:e0:a6:b5:d8:a5:
         78:fa:90:a1:aa:94:2c:35:e0:cd:9d:d1:eb:cf:14:c6:20:71:
         ed:32:e3:01:f9:70:40:19:fe:73:f9:48:e8:d6:10:58:87:f9:
         00:d9:c6:8b:ef:d3:c1:36:d8:9d:b3:8a:bb:61:c9:b7:db:83:
         a8:b1:09:31:fd:6a:e4:d9:e4:74:26:0f:6f:68:83:f6:d2:4c:
         96:35:84:bb:0a:38:e9:a4:da:23:8e:2d:f3:fb:b7:4b:55:88:
         af:c3:a2:d6:61:3d:d4:04:8f:f3:d0:7f:24:55:39:fa:a5:f3:
         6a:20:0d:59:5c:8d:8a:b3:a6:d5:00:02:30:a5:c9:64:9d:2d:
         9a:60:9a:38:01:b8:06:c8

警告

需要确保 X590v3 扩展里面有 DSN:localhost 如果您想访问 https://localhost

创建客户端证书

下面是创建客户端证书的流程, 如果您不需要 mTLS(双向认证) 则可以忽略。

生成客户端密钥

$ openssl genrsa -out private/client.key.pem 2048
Generating RSA private key, 2048 bit long modulus
.............................................+++
....................................................................+++
e is 65537 (0x10001)

生成客户端证书请求文件

$ openssl req -config openssl.ini -key private/client.key.pem -new -sha256 -reqexts req_ext -out csr/client.csr.pem -subj '/CN=client/O=QiYuTech/ST=BeiJing/C=CN'

生成客户端证书

$ openssl ca -batch -config openssl.ini -extensions usr_cert -days 375 -notext -md sha256 -in csr/client.csr.pem -out certs/client.cert.pem
Using configuration from openssl.ini
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4097 (0x1001)
        Validity
            Not Before: Sep 13 08:26:42 2021 GMT
            Not After : Sep 23 08:26:42 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BeiJing
            organizationName          = QiYuTech
            commonName                = client
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, S/MIME
            Netscape Comment: 
                OpenSSL Generated Client Certificate
            X509v3 Subject Key Identifier: 
                E0:81:C0:AB:23:9B:44:66:4C:9E:22:84:C9:0B:88:A9:69:18:0F:9F
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77

            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication, E-mail Protection
Certificate is to be certified until Sep 23 08:26:42 2022 GMT (375 days)

Write out database with 1 new entries
Data Base Updated

查看客户端证书

$ openssl x509 -noout -text -in certs/client.cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4097 (0x1001)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Sep 13 08:26:42 2021 GMT
            Not After : Sep 23 08:26:42 2022 GMT
        Subject: C=CN, ST=BeiJing, O=QiYuTech, CN=client
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cd:13:38:b2:6b:b3:1a:73:50:56:a1:cb:40:d3:
                    e8:69:3d:84:d0:42:e1:64:d7:c5:6c:c2:e0:60:e4:
                    78:4b:b5:6a:49:8d:28:b0:c6:99:25:59:68:b3:83:
                    ea:8e:30:c4:08:9c:4e:e6:07:6f:d2:50:67:04:f6:
                    f9:d6:f8:d8:42:87:c0:10:81:fa:1a:6b:35:a7:a0:
                    03:71:98:ad:1b:78:7f:4f:c6:4b:83:f2:c8:49:89:
                    75:64:73:1c:86:b6:be:6e:f2:b2:e3:05:51:0f:52:
                    d5:e9:2d:c6:16:0c:6c:e1:0a:0a:c5:5b:b6:b6:6a:
                    a6:7b:c5:69:af:31:80:ee:0d:55:cf:8d:02:d9:18:
                    b7:94:41:97:20:60:3f:fc:b6:79:a0:ec:ea:ac:ac:
                    30:9a:be:0f:05:be:a5:97:7c:d9:ed:37:12:b8:8b:
                    ee:71:26:3b:ec:1c:a0:db:0e:23:81:33:8a:2c:77:
                    8f:a8:57:2f:d9:0a:8a:f8:1c:d0:46:2e:16:29:09:
                    a9:6a:ee:82:d9:d7:97:d1:92:1b:58:6e:b6:37:38:
                    23:f4:b0:0a:e8:32:6d:37:73:78:16:43:f4:08:fe:
                    e8:06:c8:31:e9:8d:37:99:c7:3c:4a:47:1f:c7:92:
                    37:1f:19:40:2f:17:42:28:35:25:a2:b8:98:2e:e7:
                    ba:03
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, S/MIME
            Netscape Comment: 
                OpenSSL Generated Client Certificate
            X509v3 Subject Key Identifier: 
                E0:81:C0:AB:23:9B:44:66:4C:9E:22:84:C9:0B:88:A9:69:18:0F:9F
            X509v3 Authority Key Identifier: 
                keyid:BC:37:FF:2E:B3:D8:05:8A:EB:4E:B9:3E:20:E8:0D:A7:D0:4C:AC:77

            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication, E-mail Protection
    Signature Algorithm: sha256WithRSAEncryption
         b1:d6:b0:6b:31:70:1f:93:1e:61:d7:bf:21:ee:85:77:d2:0a:
         81:60:eb:f4:b3:c2:a7:5e:80:5b:0d:4a:04:a9:44:ac:4c:86:
         da:86:72:54:12:d9:07:41:07:4f:4c:82:84:de:b4:b3:f2:dc:
         9f:2d:12:73:a4:35:7f:7a:d8:2d:36:c5:60:93:ad:29:c0:d6:
         88:3a:11:18:21:6e:ec:a1:0a:35:a2:d5:06:f4:63:59:3f:45:
         62:e9:2e:58:ff:ea:3b:85:fd:70:69:55:96:4e:e6:0f:2d:b2:
         82:e1:fc:b0:45:26:d2:ac:81:51:1f:03:6e:b7:5c:b4:c7:3c:
         26:39:d4:50:1a:b8:f9:e7:ac:f0:3a:15:c7:e9:01:e1:a1:10:
         6e:c6:1b:2c:54:7c:00:c4:64:d3:7e:bb:f2:1e:9b:fc:60:a0:
         b4:c0:fc:93:6a:f4:6e:2a:a5:eb:aa:de:fd:5f:4c:a3:cd:e9:
         92:09:9b:66:e1:59:b9:87:8f:cc:0d:0a:84:6d:8f:a1:bc:82:
         8b:d8:7d:0f:ab:3a:ec:e7:c8:db:d2:43:e3:62:b9:79:cc:bd:
         51:fb:11:86:28:ba:a7:86:fb:06:73:23:cf:d7:7c:a4:fd:bd:
         52:61:be:c0:92:e3:0a:06:e3:16:30:ab:b4:02:a7:82:e4:1d:
         d9:f5:15:af:07:45:ad:0d:97:bf:ce:5e:a0:42:b4:f8:76:af:
         7c:d6:78:0c:e5:8d:aa:16:4b:8f:a5:45:9b:fa:90:a4:75:cf:
         ce:58:8a:4b:6a:ae:b1:b5:f6:01:f7:8b:15:28:40:96:fe:31:
         1d:ac:4f:eb:07:74:11:0c:8d:23:56:01:79:93:d0:68:c4:b5:
         f7:dd:4e:35:c2:77:47:72:89:d3:0c:3c:b2:6d:20:8b:28:d5:
         11:62:6e:15:76:0d:d9:d6:66:d1:14:49:58:5d:ef:76:13:6f:
         47:f3:fe:20:e3:f7:08:8e:5b:9c:cf:b4:31:55:d1:fc:32:b3:
         19:a1:fb:62:0d:65:9e:8d:fe:b4:d6:8c:75:7b:f8:ed:50:ba:
         7c:d1:33:35:a5:21:72:c6:02:e0:eb:44:7f:e9:32:1d:80:cc:
         0c:f9:c0:f7:43:07:2a:7c:74:d4:97:75:c6:45:f1:71:93:ce:
         fb:30:4f:ba:3c:6a:ba:72:95:aa:ec:d3:ae:e0:b6:05:8e:a1:
         d1:3d:be:f5:e8:38:4b:1c:9f:4f:5c:38:b7:83:93:84:7a:c0:
         3d:53:db:2a:a4:ba:34:d7:2f:48:71:60:de:4a:7b:d6:49:1c:
         e8:07:24:e4:3b:8c:0b:b0:1f:6a:13:af:b9:2f:6f:eb:9a:b8:
         0b:52:6d:64:40:94:36:27

客户端生成 p12 文件

一般客户端使用的都是 p12 文件,方便用户导入导出。

$ openssl pkcs12 -export -clcerts -in certs/client.cert.pem -inkey private/client.key.pem -out pkcs12/client.p12 -passout pass:

警告

实际使用中请不要导出没有密码保护的文件。

结论

走完上面的流程,您的自签名根证书已经创建完成。 以后只需要根据自己的需要,添加新的服务器端证书、客户端证书就可以了。

警告

上面的教程只适合您在本地开发环境使用(或者其他情况下的自用),生产环境请从权威机构购买证书 或 寻求密码学专家的帮助。

使用上面代码导致任何问题,概不负责(上面的内容本身就忽略了一些安全领域的最佳实践)。

现在让我们看一下走完以上流程的目录结果:

$ tree .
.
├── Makefile
├── certs
│   ├── ca.cert.pem
│   ├── client.cert.pem
│   └── localhost.cert.pem
├── csr
│   ├── client.csr.pem
│   └── localhost.csr.pem
├── index.txt
├── index.txt.attr
├── index.txt.attr.old
├── index.txt.old
├── newcerts
│   ├── 1000.pem
│   └── 1001.pem
├── openssl.ini
├── pkcs12
│   └── client.p12
├── private
│   ├── ca.key.pem
│   ├── client.key.pem
│   └── localhost.key.pem
├── serial
└── serial.old

5 directories, 19 files

其中:

  • .gitignore

  • Makefile

  • openssl.ini

文件可以忽略,不是以上命令生成的内容。

从上面的结果我们可以知道, 我们

  • 生成了 3 个私钥文件(在 private 目录, 分别对应 根证书(ca)、服务器端证书(localhost)、客户端证书(client))

  • 生成了 3 个证书文件(在 certs 目录, 分别对应 根证书(ca)、服务器端证书(localhost)、客户端证书(client))

  • 生成了 2 个证书请求文件 (在 csr 目录, 分别对应 服务器端证书请求(localhost)、客户端证书请求(client))

其他的文件都是由 openssl 自动生成用户管理的。

福利

看完了上面的教程,是不是脑袋还是晕晕的,对于怎么样才能生成自己的根证书、服务器端证书、客户端证书还是有所迷茫,

这都没关系.

保存下面的 Makefile 文件到一个空目录:

# 创建干净的测试环境
# 注意: 如果您的目录中已经有证书,则会被删除
# 请复制到一个新的空目录使用
clean-all:
	rm -rf certs csr newcerts pkcs12 private index* serial*
	mkdir certs
	mkdir csr
	mkdir newcerts
	mkdir pkcs12
	mkdir private
	echo "1000" > serial
	touch index.txt

# 生成根密钥
gen-root-key:
	openssl genrsa -out private/ca.key.pem 4096

# 生成根证书
gen-root-certificate:
	openssl req -config openssl.ini                   \
      -key private/ca.key.pem                         \
      -new -x509 -days 7300 -sha256 -extensions v3_ca \
      -out certs/ca.cert.pem

# 查看根证书
view-root-certificate:
	openssl x509 -noout -text -in certs/ca.cert.pem


# 生成服务器端密钥
gen-server-key:
	openssl genrsa -out private/localhost.key.pem 2048


# 生成服务器端 CSR 文件
gen-server-csr:
	openssl req -config openssl.ini      \
          -key private/localhost.key.pem \
          -new -sha256                   \
          -reqexts req_ext               \
          -out csr/localhost.csr.pem

# 查看服务器端 CSR 文件
view-server-csr:
	openssl req -in csr/localhost.csr.pem -noout -text


# 生成服务器端证书
gen-server-certificate:
	openssl ca -config openssl.ini \
          -extensions server_cert -days 375 -notext -md sha256 \
          -in csr/localhost.csr.pem \
          -out certs/localhost.cert.pem


# 查看服务器端证书
view-server-certificate:
	openssl x509 -noout -text -in certs/localhost.cert.pem


# 生成客户端密钥
gen-client-key:
	openssl genrsa -out private/client.key.pem 2048


# 生成客户端 CSR 文件
gen-client-csr:
	openssl req -config openssl.ini      \
          -key private/client.key.pem \
          -new -sha256                   \
          -reqexts req_ext               \
          -out csr/client.csr.pem


# 生成客户端证书
gen-client-certificate:
	openssl ca -config openssl.ini \
          -extensions usr_cert -days 375 -notext -md sha256 \
          -in  csr/client.csr.pem \
          -out certs/client.cert.pem

# 查看客户端证书
view-client-certificate:
	openssl x509 -noout -text -in certs/client.cert.pem

# 生成客户端 p12 文件
gen-client-pkcs12:
	openssl pkcs12              \
		-export -clcerts        \
		-in    certs/client.cert.pem \
		-inkey private/client.key.pem \
		-out   pkcs12/client.p12

然后就可以愉快的使用 make 命令生成属于您自己的自签名证书啦。

当然, openssl.ini 配置也不能少:

警告

需要保存此文件为 openssl.ini 并且和 Makefile 文件在同一个目录下面。

# OpenSSL 根证书配置文件
# 可以复制到 `/root/ca/openssl.cnf` 方便使用

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# 目录及文件的存放的位置
# dir 需要改成您 自己的目录
dir = /Users/dabaichi/Projects/dabaichi/Blogs/QiYuTech/source/202103/09_self_sign_cert
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand

# 根 密钥 和 根 证书
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pem

# CRL(证书撤销列表) 配置
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30

# SHA-1 已经不在安全, 我们使用 SHA-2
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

# need add req extensions
req_extensions = req_ext

#
# copy https://gist.github.com/croxton/ebfb5f3ac143cd86542788f972434c96
#
[ req_ext ]
subjectAltName = @alt_names

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
organizationName = Organization Name (eg, company)
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (eg, server FQDN or YOUR name)
emailAddress = Email Address (eg, admin@example.com)

# 我们配置的默认值
# 您应该更改为您需要使用的默认值
countryName_default = CN
stateOrProvinceName_default = BeiJing
localityName_default = BeiJing
organizationName_default = QiYuTech
organizationalUnitName_default = Auth
emailAddress_default = dev@qiyutech.tech

[ 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
#
# https://stackoverflow.com/questions/21488845/how-can-i-generate-a-self-signed-certificate-with-subjectaltname-using-openssl
#
subjectAltName = @alt_names

[ 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 = "QiYuTech Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

# add the DNS
subjectAltName = @alt_names

[ 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

# 参考: https://gist.github.com/croxton/ebfb5f3ac143cd86542788f972434c96
# 我们给 localhost 签名
[ alt_names ]

DNS.1 = localhost
DNS.2 = 127.0.0.1
DNS.3 = ::1