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

虽然我们不经常创建证书(尤其是根证书,申请 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: 10692682464236700298 (0x94640a0c88e0828a)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Feb 20 09:07:07 2022 GMT
            Not After : Feb 15 09:07:07 2042 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:da:3d:4c:b4:3c:77:a5:3c:b6:0f:0f:47:bd:83:
                    fd:a4:45:10:f1:55:5e:d7:77:1a:2a:a5:a3:b2:06:
                    05:ea:55:61:98:ee:81:a4:36:0c:ca:d4:5c:2e:cc:
                    74:8c:5d:65:37:23:92:cb:d7:40:64:bc:d8:6f:8b:
                    7e:58:01:73:8d:df:85:5d:07:fd:ed:98:d6:01:e4:
                    4a:7f:0f:98:6c:fb:17:69:b8:28:d6:c0:f4:bc:90:
                    69:4f:ba:e7:0c:e4:6e:5e:fb:ed:c4:ac:7f:f8:dc:
                    1f:a6:c3:cd:69:a2:e1:41:39:7b:4a:bb:62:d1:71:
                    f6:21:ef:d7:9d:3c:d0:2a:cb:10:c3:e3:c0:f9:e6:
                    64:29:2a:b8:ef:51:e4:ef:04:fa:82:25:41:4e:0f:
                    e0:01:9d:b7:1c:25:c1:71:73:6c:1f:e8:f2:93:a2:
                    43:bf:d9:ee:81:45:6c:28:6f:7e:1a:f2:38:09:cf:
                    74:2d:6f:79:e6:2c:2c:36:c4:de:50:07:b0:92:51:
                    8f:22:a0:79:db:48:ba:51:15:ac:b3:a8:b5:cc:3c:
                    d2:80:d0:2a:6f:8e:b4:b3:5e:aa:d2:2f:17:f2:95:
                    5a:dc:e5:a8:ea:da:67:3f:a7:66:fb:04:c6:98:7f:
                    06:25:9a:1f:bb:dc:60:cc:25:45:1a:dc:d6:8a:2f:
                    87:36:db:24:8d:93:3d:8e:1e:63:94:22:6a:13:fd:
                    f4:93:6d:6e:f0:c4:99:c3:d5:26:e0:c5:66:03:a1:
                    e0:b7:80:77:8e:be:f7:7e:d0:a7:34:c4:fc:6b:14:
                    79:c9:e2:9b:b5:be:dc:39:62:d8:41:0f:52:4f:1b:
                    cd:67:86:05:7d:94:c1:1d:03:96:d2:b3:9f:81:f8:
                    57:8c:3a:56:e1:5c:fc:73:77:5a:36:58:a6:a3:38:
                    cd:2b:77:b9:33:43:49:60:c2:2f:d1:76:c5:4c:40:
                    b4:b5:b3:65:29:ac:05:e8:10:b8:2c:62:8b:08:d1:
                    de:fc:cf:86:59:80:6d:eb:91:13:fd:1e:09:59:97:
                    75:bf:c9:50:60:77:8c:1e:3e:7b:da:76:42:83:9b:
                    ee:fd:2d:7a:7f:f4:32:ff:9c:bc:7b:9a:d8:52:eb:
                    98:7e:cf:a7:0c:03:70:12:35:f0:b5:d8:d8:82:26:
                    20:2e:fc:2b:01:c4:a6:ac:19:92:77:b1:e3:11:93:
                    ee:1c:fe:a9:d2:6f:bf:de:1d:54:cf:7c:31:9b:6b:
                    6a:95:fd:10:43:91:b6:d1:a5:af:42:1b:f7:6c:24:
                    3a:37:99:c8:5a:ed:0e:d0:3f:20:e0:5b:d1:a5:34:
                    22:77:c2:8c:70:7e:b0:f9:41:52:d4:ae:54:42:78:
                    d9:11:ad
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1

            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
         99:ff:21:e0:42:d0:89:c0:2e:0d:3d:94:56:40:1a:85:22:4e:
         e2:03:b0:9a:36:d2:19:2a:79:4c:a5:4d:3d:14:02:60:8d:cf:
         12:b5:b2:ba:c8:48:b7:59:51:16:37:55:9c:42:e4:81:f4:15:
         d5:e4:0e:c4:a4:4a:7d:2f:af:51:7c:ed:61:11:e6:9f:37:99:
         fe:76:fb:6a:21:6d:ce:9e:b1:8f:d1:56:a1:18:b0:41:d9:fa:
         79:e6:08:73:87:73:e7:9b:41:9d:2c:b4:84:bb:64:6d:d8:29:
         4b:ed:e3:00:ed:bb:88:39:1f:29:99:e9:4a:78:c8:0c:a4:c8:
         05:e4:66:f9:4e:49:05:95:c6:65:62:79:97:b2:9b:7d:08:ce:
         b2:d0:ae:5f:70:8f:70:80:a8:e8:e6:57:59:d0:4f:89:14:a6:
         16:78:7e:dd:49:26:3d:b7:71:7b:75:9e:d8:3d:4d:b6:12:fe:
         31:25:e9:63:9c:da:40:ff:f5:51:12:1c:76:6b:49:af:2a:cf:
         49:e2:5c:f3:c0:cb:30:91:68:40:31:f4:d6:cb:4c:34:72:b2:
         28:48:1d:f0:7c:34:d4:ce:f5:39:cd:73:1d:e3:0f:d3:5d:0a:
         53:39:f2:ae:4c:0d:5d:6b:e6:5c:82:43:9f:f7:ed:60:27:33:
         79:89:92:51:bf:72:1c:52:9a:02:da:50:96:77:41:b1:29:51:
         68:5a:72:b8:d3:7f:fe:c1:23:b1:1c:77:92:05:6f:f0:2f:18:
         4d:0d:92:7a:71:b8:1d:d2:9c:d6:58:ac:07:71:a0:1f:16:7e:
         b2:ad:a6:7a:25:a1:7d:57:73:93:7e:f8:72:26:e3:70:d5:b0:
         35:af:fe:30:1c:40:39:b4:d2:a7:d7:7c:fb:95:e0:de:2c:07:
         6f:76:83:5d:63:8e:d3:5d:b9:2f:bd:b6:08:c0:d3:25:9b:d7:
         a6:ba:1a:c0:54:61:23:02:08:d6:53:94:05:59:31:27:df:09:
         c8:d0:62:cc:55:1e:c7:e1:92:a7:30:95:91:58:ec:b5:19:c6:
         21:c3:13:49:3e:2f:26:23:d3:e6:12:3a:68:d5:d5:9a:9e:4d:
         be:a0:05:1d:11:c7:0f:b2:fe:82:92:17:bf:54:0f:d9:ea:83:
         66:dd:77:b3:b1:c5:d8:1b:17:66:d5:e1:f6:8b:d5:5d:c4:a7:
         db:d6:59:71:74:f6:41:39:16:09:c4:38:a3:6f:ba:58:79:95:
         cb:38:95:d1:52:0f:75:79:3a:eb:5e:e6:42:d7:56:16:96:63:
         b6:d9:62:6d:61:67:e6:4b:93:19:5b:0f:1b:3b:8d:d3:26:96:
         a6:5d:07:d7:7a:27:1b:cd

创建服务器证书

现在让我们使用上面创建的根证书,创建一个我们可以使用的 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: 10692682464236700298 (0x94640a0c88e0828a)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Feb 20 09:07:07 2022 GMT
            Not After : Feb 15 09:07:07 2042 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:da:3d:4c:b4:3c:77:a5:3c:b6:0f:0f:47:bd:83:
                    fd:a4:45:10:f1:55:5e:d7:77:1a:2a:a5:a3:b2:06:
                    05:ea:55:61:98:ee:81:a4:36:0c:ca:d4:5c:2e:cc:
                    74:8c:5d:65:37:23:92:cb:d7:40:64:bc:d8:6f:8b:
                    7e:58:01:73:8d:df:85:5d:07:fd:ed:98:d6:01:e4:
                    4a:7f:0f:98:6c:fb:17:69:b8:28:d6:c0:f4:bc:90:
                    69:4f:ba:e7:0c:e4:6e:5e:fb:ed:c4:ac:7f:f8:dc:
                    1f:a6:c3:cd:69:a2:e1:41:39:7b:4a:bb:62:d1:71:
                    f6:21:ef:d7:9d:3c:d0:2a:cb:10:c3:e3:c0:f9:e6:
                    64:29:2a:b8:ef:51:e4:ef:04:fa:82:25:41:4e:0f:
                    e0:01:9d:b7:1c:25:c1:71:73:6c:1f:e8:f2:93:a2:
                    43:bf:d9:ee:81:45:6c:28:6f:7e:1a:f2:38:09:cf:
                    74:2d:6f:79:e6:2c:2c:36:c4:de:50:07:b0:92:51:
                    8f:22:a0:79:db:48:ba:51:15:ac:b3:a8:b5:cc:3c:
                    d2:80:d0:2a:6f:8e:b4:b3:5e:aa:d2:2f:17:f2:95:
                    5a:dc:e5:a8:ea:da:67:3f:a7:66:fb:04:c6:98:7f:
                    06:25:9a:1f:bb:dc:60:cc:25:45:1a:dc:d6:8a:2f:
                    87:36:db:24:8d:93:3d:8e:1e:63:94:22:6a:13:fd:
                    f4:93:6d:6e:f0:c4:99:c3:d5:26:e0:c5:66:03:a1:
                    e0:b7:80:77:8e:be:f7:7e:d0:a7:34:c4:fc:6b:14:
                    79:c9:e2:9b:b5:be:dc:39:62:d8:41:0f:52:4f:1b:
                    cd:67:86:05:7d:94:c1:1d:03:96:d2:b3:9f:81:f8:
                    57:8c:3a:56:e1:5c:fc:73:77:5a:36:58:a6:a3:38:
                    cd:2b:77:b9:33:43:49:60:c2:2f:d1:76:c5:4c:40:
                    b4:b5:b3:65:29:ac:05:e8:10:b8:2c:62:8b:08:d1:
                    de:fc:cf:86:59:80:6d:eb:91:13:fd:1e:09:59:97:
                    75:bf:c9:50:60:77:8c:1e:3e:7b:da:76:42:83:9b:
                    ee:fd:2d:7a:7f:f4:32:ff:9c:bc:7b:9a:d8:52:eb:
                    98:7e:cf:a7:0c:03:70:12:35:f0:b5:d8:d8:82:26:
                    20:2e:fc:2b:01:c4:a6:ac:19:92:77:b1:e3:11:93:
                    ee:1c:fe:a9:d2:6f:bf:de:1d:54:cf:7c:31:9b:6b:
                    6a:95:fd:10:43:91:b6:d1:a5:af:42:1b:f7:6c:24:
                    3a:37:99:c8:5a:ed:0e:d0:3f:20:e0:5b:d1:a5:34:
                    22:77:c2:8c:70:7e:b0:f9:41:52:d4:ae:54:42:78:
                    d9:11:ad
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1

            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
         99:ff:21:e0:42:d0:89:c0:2e:0d:3d:94:56:40:1a:85:22:4e:
         e2:03:b0:9a:36:d2:19:2a:79:4c:a5:4d:3d:14:02:60:8d:cf:
         12:b5:b2:ba:c8:48:b7:59:51:16:37:55:9c:42:e4:81:f4:15:
         d5:e4:0e:c4:a4:4a:7d:2f:af:51:7c:ed:61:11:e6:9f:37:99:
         fe:76:fb:6a:21:6d:ce:9e:b1:8f:d1:56:a1:18:b0:41:d9:fa:
         79:e6:08:73:87:73:e7:9b:41:9d:2c:b4:84:bb:64:6d:d8:29:
         4b:ed:e3:00:ed:bb:88:39:1f:29:99:e9:4a:78:c8:0c:a4:c8:
         05:e4:66:f9:4e:49:05:95:c6:65:62:79:97:b2:9b:7d:08:ce:
         b2:d0:ae:5f:70:8f:70:80:a8:e8:e6:57:59:d0:4f:89:14:a6:
         16:78:7e:dd:49:26:3d:b7:71:7b:75:9e:d8:3d:4d:b6:12:fe:
         31:25:e9:63:9c:da:40:ff:f5:51:12:1c:76:6b:49:af:2a:cf:
         49:e2:5c:f3:c0:cb:30:91:68:40:31:f4:d6:cb:4c:34:72:b2:
         28:48:1d:f0:7c:34:d4:ce:f5:39:cd:73:1d:e3:0f:d3:5d:0a:
         53:39:f2:ae:4c:0d:5d:6b:e6:5c:82:43:9f:f7:ed:60:27:33:
         79:89:92:51:bf:72:1c:52:9a:02:da:50:96:77:41:b1:29:51:
         68:5a:72:b8:d3:7f:fe:c1:23:b1:1c:77:92:05:6f:f0:2f:18:
         4d:0d:92:7a:71:b8:1d:d2:9c:d6:58:ac:07:71:a0:1f:16:7e:
         b2:ad:a6:7a:25:a1:7d:57:73:93:7e:f8:72:26:e3:70:d5:b0:
         35:af:fe:30:1c:40:39:b4:d2:a7:d7:7c:fb:95:e0:de:2c:07:
         6f:76:83:5d:63:8e:d3:5d:b9:2f:bd:b6:08:c0:d3:25:9b:d7:
         a6:ba:1a:c0:54:61:23:02:08:d6:53:94:05:59:31:27:df:09:
         c8:d0:62:cc:55:1e:c7:e1:92:a7:30:95:91:58:ec:b5:19:c6:
         21:c3:13:49:3e:2f:26:23:d3:e6:12:3a:68:d5:d5:9a:9e:4d:
         be:a0:05:1d:11:c7:0f:b2:fe:82:92:17:bf:54:0f:d9:ea:83:
         66:dd:77:b3:b1:c5:d8:1b:17:66:d5:e1:f6:8b:d5:5d:c4:a7:
         db:d6:59:71:74:f6:41:39:16:09:c4:38:a3:6f:ba:58:79:95:
         cb:38:95:d1:52:0f:75:79:3a:eb:5e:e6:42:d7:56:16:96:63:
         b6:d9:62:6d:61:67:e6:4b:93:19:5b:0f:1b:3b:8d:d3:26:96:
         a6:5d:07:d7:7a:27:1b:cd

重要

一定要确保生成的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: Feb 20 09:07:07 2022 GMT
            Not After : Mar  2 09:07:07 2023 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: 
                5D:1B:58:9F:BE:A1:4C:ED:A5:42:D7:8A:E6:69:F3:90:8B:68:20:5D
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:94:64:0A:0C:88:E0:82:8A

            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 Mar  2 09:07:07 2023 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: Feb 20 09:07:07 2022 GMT
            Not After : Mar  2 09:07:07 2023 GMT
        Subject: C=CN, ST=BeiJing, O=QiYuTech, CN=localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:bc:78:51:7e:08:54:13:57:04:0d:63:92:bc:72:
                    af:88:d4:30:e7:d9:8f:1d:86:1c:a5:62:d8:3a:91:
                    1d:85:77:f3:93:43:48:1a:7c:87:d8:31:fd:3b:b8:
                    7d:27:60:31:aa:8b:4c:24:be:10:ac:81:c8:f2:10:
                    8c:d2:92:d3:32:7c:b8:a4:52:7f:7b:2a:b1:f2:83:
                    71:7e:91:57:58:25:73:b4:23:d0:4c:63:4a:7d:3d:
                    dc:5e:29:ce:9b:97:c2:a9:95:fc:a4:8b:aa:fb:7e:
                    3f:d3:d6:b7:48:c9:95:e9:7e:bf:16:3d:a3:a8:85:
                    b2:60:b3:19:15:ab:42:2d:9a:65:1e:d2:0a:2b:6d:
                    e6:8c:8f:6f:47:97:27:5e:25:1c:bc:b9:99:9b:89:
                    e3:bd:74:38:12:0a:95:cf:14:33:ad:8e:8d:82:76:
                    1e:fe:fc:6a:17:07:86:e5:ac:b6:20:f9:40:15:d8:
                    c8:cf:83:db:66:bd:58:12:19:2d:3f:61:65:4a:4d:
                    04:20:89:7e:1b:d2:09:bc:da:ab:1f:c5:dc:12:fd:
                    fe:7e:f7:de:b6:50:44:d3:df:e0:73:d6:1c:6f:43:
                    5d:a1:af:ab:bc:97:07:44:64:05:e2:c2:d6:2c:ac:
                    fc:3b:ea:d7:e4:b4:1b:2f:bf:b0:dd:56:d6:39:fe:
                    c9:ed
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                QiYuTech Server Certificate
            X509v3 Subject Key Identifier: 
                5D:1B:58:9F:BE:A1:4C:ED:A5:42:D7:8A:E6:69:F3:90:8B:68:20:5D
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:94:64:0A:0C:88:E0:82:8A

            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
         88:ac:80:ae:b3:30:90:d7:61:39:25:7f:ad:07:cb:81:04:1d:
         d4:ac:a6:f4:33:a5:e1:5c:e0:1c:f8:f1:88:16:f8:04:38:14:
         ee:b5:bc:59:35:c2:f9:ca:c2:fd:2e:90:7b:5a:a2:28:77:91:
         51:18:eb:29:9a:e3:b6:b6:ca:41:98:85:91:bf:28:cc:b6:1e:
         76:ca:5e:35:ba:8c:a5:41:1d:8f:87:e0:c0:56:c9:2a:fd:56:
         ed:c8:c6:c8:8c:7d:1f:e7:08:e6:9e:f0:8b:86:ac:8e:33:30:
         86:31:78:65:e7:59:3f:66:d3:a2:b2:1e:55:93:1a:e6:3c:a0:
         b8:04:4f:2a:3c:70:8a:87:e7:21:d5:a3:7a:9a:c8:20:48:3c:
         9a:59:f9:e8:1e:40:0c:65:c5:85:0b:8d:ff:c3:77:f6:b4:5d:
         09:a6:df:c1:57:58:e6:bc:54:3b:c0:36:cd:6c:f9:f5:02:24:
         39:d9:99:16:36:ca:58:ee:59:f2:0e:1a:9c:3c:0a:7b:6a:e8:
         f5:4c:e5:be:76:56:c1:6d:2f:e7:84:2b:86:4b:cc:22:5c:8e:
         2d:df:b5:10:56:62:f2:66:2f:75:70:85:08:b2:47:59:cb:9d:
         f5:aa:90:1d:23:6a:46:f3:60:dc:50:4a:90:2b:9b:c6:46:61:
         b8:a3:fd:8e:9a:da:a9:5d:4e:a5:9e:1c:bf:53:48:a0:57:f1:
         4c:42:54:93:31:be:96:dd:32:f6:e3:07:28:fb:33:96:1b:a3:
         dd:97:9a:8c:31:ca:99:e4:f3:bf:49:24:cb:d6:e5:b7:c1:c9:
         20:92:a6:dd:77:9d:13:b2:0d:17:a8:9e:4e:fd:92:ee:d8:20:
         5b:a5:2f:ca:f0:ca:8f:b3:1e:6d:6b:7f:3c:38:84:30:ed:ae:
         8e:25:25:4c:29:10:b2:0a:94:57:6e:e2:81:2d:2c:ec:47:81:
         e0:75:21:0f:4c:cb:05:f7:af:ea:20:fd:d7:96:3a:7c:52:23:
         9c:9e:4d:67:47:0d:f8:b5:f6:19:9c:f7:ec:2c:85:3e:ab:c8:
         96:ef:3e:55:35:8a:f0:4b:54:f6:0c:5e:89:7c:aa:97:87:a0:
         1a:d2:50:55:7a:26:56:a5:17:58:0f:6d:3f:fe:e2:b2:3b:81:
         16:af:5e:cc:82:e9:69:db:6a:ee:5f:69:32:b1:f1:89:27:87:
         9e:bd:58:54:ad:00:4a:a4:e4:e5:56:28:82:43:6e:9e:7d:48:
         52:5e:ba:c0:ee:b1:3e:bf:c7:8e:c7:44:97:30:67:e1:14:8a:
         a5:8b:5d:aa:36:b4:9b:ee:45:41:65:c2:bf:50:b9:c6:ba:3f:
         5c:a0:dc:e2:03:23:44:88

警告

需要确保 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: Feb 20 09:07:07 2022 GMT
            Not After : Mar  2 09:07:07 2023 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: 
                AE:0F:12:07:DC:71:98:50:F6:04:43:79:49:18:CC:DE:C0:6F:CE:D6
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1

            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 Mar  2 09:07:07 2023 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: Feb 20 09:07:07 2022 GMT
            Not After : Mar  2 09:07:07 2023 GMT
        Subject: C=CN, ST=BeiJing, O=QiYuTech, CN=client
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:df:93:e2:33:0b:15:24:48:23:e6:45:3a:ba:84:
                    d8:1e:0a:d7:85:c7:8f:03:a3:23:25:cc:fb:c2:0c:
                    d0:9a:d9:e4:60:59:ef:48:d0:a5:17:2c:ac:55:90:
                    9f:85:8e:61:0d:27:ee:53:bf:a6:47:be:f2:7f:f2:
                    01:98:cb:14:96:04:de:08:8e:d5:15:3d:c6:93:a2:
                    33:1c:d2:97:97:ee:fc:e6:93:95:8d:0b:18:45:da:
                    19:93:80:9c:d5:a0:ca:92:46:cc:af:8f:08:a8:9d:
                    e0:98:a4:c0:e9:f1:e1:be:99:0a:1d:33:89:ac:cf:
                    eb:35:82:c8:bf:d5:b2:75:9a:ac:77:4c:0e:eb:2e:
                    cd:9b:9c:59:2e:45:30:4b:54:14:0c:d3:68:ae:12:
                    96:aa:87:6c:9f:dd:ac:7e:b6:70:03:d2:62:93:28:
                    71:da:b1:60:c0:33:25:6b:dd:0e:e3:d0:c8:86:a9:
                    5c:de:f9:72:a1:5e:f5:7c:e3:a6:4b:77:0b:92:bd:
                    9f:db:48:c0:4b:cc:b3:5b:0c:17:06:51:ae:6b:67:
                    14:97:79:b5:1c:e1:48:0e:66:fc:55:21:ff:b1:48:
                    6a:75:f4:09:a0:b5:a7:0a:60:8f:d8:78:51:f0:0a:
                    2b:d7:4a:3d:e0:4a:36:c1:ea:e4:aa:c7:a8:d9:a3:
                    d4:fd
                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: 
                AE:0F:12:07:DC:71:98:50:F6:04:43:79:49:18:CC:DE:C0:6F:CE:D6
            X509v3 Authority Key Identifier: 
                keyid:A2:27:8C:3D:0B:35:D0:64:FB:EB:B3:DB:60:9B:6B:07:D4:C1:D7:C1

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

客户端生成 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