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

虽然我们不经常创建证书(尤其是根证书,申请 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: 16405080066384587582 (0xe3aa8d670cb1eb3e)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Oct 16 11:55:06 2021 GMT
            Not After : Oct 11 11:55:06 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:be:8a:1e:dd:ea:c1:5f:1a:7c:a0:31:1c:52:61:
                    19:0e:35:48:48:f7:49:68:e1:0e:05:6e:36:c2:2d:
                    19:06:c6:3d:5f:08:b5:36:f6:77:a1:f6:e0:2f:f0:
                    1f:88:b2:3b:f3:8a:c0:b9:7a:58:aa:17:b1:6d:6f:
                    25:15:ce:93:bb:e5:d1:91:f7:da:56:ce:d7:0a:21:
                    6a:d6:02:26:c7:50:11:41:d8:49:28:13:ff:32:20:
                    3a:75:6c:74:e2:a0:74:a1:b3:6f:2e:a5:46:85:19:
                    66:6c:68:b2:ea:fe:e1:4a:ec:c2:dd:20:41:2d:0d:
                    02:01:61:e0:d1:99:35:6f:d6:3a:07:e0:a4:2e:74:
                    a0:ef:8e:53:2f:9c:16:4a:2d:df:21:f4:5b:a6:a8:
                    eb:a9:3d:08:36:ca:08:8d:d4:5d:9e:ef:bb:a1:08:
                    70:96:7f:43:fb:04:3c:f5:26:4c:eb:bc:b5:63:fa:
                    b5:34:05:95:90:9d:f5:b3:19:45:b5:35:56:49:1c:
                    a6:b3:c9:78:ba:4e:f0:a8:86:3e:50:19:06:dc:b2:
                    7b:6a:09:c4:f2:90:7e:3f:21:10:db:31:43:30:aa:
                    52:cb:1f:d7:ad:2f:cb:d2:11:6b:64:6c:46:b3:3f:
                    8e:fc:79:da:36:ce:86:8a:4c:7f:6c:3b:76:a1:e4:
                    fb:fe:82:3a:d3:9f:7b:2b:92:80:d5:84:d1:49:4c:
                    43:7e:29:3e:c1:ba:6e:95:30:80:04:4b:eb:cb:1d:
                    8b:55:2e:f3:2f:e5:27:68:52:94:47:04:be:e2:91:
                    e0:5a:28:47:e4:47:1c:32:41:d9:f0:d7:52:76:78:
                    f7:8b:46:b3:24:4e:e1:27:fd:e6:1d:66:f6:29:15:
                    79:f1:b6:b0:80:c2:76:1a:99:b6:f4:f0:a5:8b:f0:
                    3f:e8:0b:cb:70:3f:dd:0d:57:01:bd:19:21:d2:3b:
                    ff:44:66:79:d1:a5:f3:a0:6d:c6:b6:f5:c2:76:7c:
                    c9:3e:db:10:79:b0:83:39:f7:e7:7e:44:6c:2c:29:
                    42:77:71:68:3f:5d:9a:56:02:84:a8:e9:7b:36:53:
                    5f:a6:a0:20:2e:50:2c:e7:ff:1c:4d:94:6c:aa:2c:
                    ab:a3:ed:ed:c5:60:74:7a:00:50:b9:f5:d6:ff:43:
                    64:cc:84:d7:b4:96:69:fc:e1:56:50:93:58:14:cc:
                    40:86:e2:e4:f0:a0:95:64:98:8c:1d:2e:9b:2e:36:
                    11:19:62:96:4d:bc:47:72:95:89:d5:a9:64:5c:48:
                    cc:10:2a:d7:94:ab:57:19:b9:b9:46:4a:de:e1:ad:
                    19:93:9c:de:a6:09:1d:26:64:c9:f5:96:eb:ad:94:
                    b7:29:45
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2

            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
         28:44:f7:5a:e5:54:e2:71:a0:47:c1:76:11:27:0f:bc:fd:93:
         06:a7:03:19:f7:36:33:80:f8:20:7b:41:34:21:09:43:ea:a5:
         0c:f9:0d:f7:91:36:61:d4:4a:20:5f:32:b3:87:39:81:f8:26:
         4c:89:21:b5:dd:c3:bd:fc:6e:63:c7:2c:8a:77:f4:c1:a5:b3:
         52:bd:4a:18:52:9b:4b:62:1a:f4:62:3e:0e:05:83:5e:3e:e7:
         2e:69:f9:6a:0e:4f:73:b1:93:c1:de:ca:8f:d3:a5:81:f9:41:
         6b:86:60:46:26:af:71:ca:ca:47:d0:91:3f:b7:22:f2:47:13:
         f7:44:4e:ce:47:be:1a:17:39:d4:b1:de:d7:0e:c2:10:0f:39:
         5b:74:c4:21:c4:06:a7:6a:33:3b:83:3f:5d:a5:89:e9:0d:61:
         cd:3a:35:7e:24:79:21:d0:3a:8b:d7:45:44:97:88:71:04:7f:
         5a:a4:0c:81:d5:b6:06:6e:7e:a2:96:97:ce:51:03:98:4f:ef:
         b5:f8:55:eb:77:ad:37:36:88:ea:e8:95:28:a5:39:2c:83:b5:
         3b:2b:c5:a8:31:2a:27:22:0e:34:73:82:0d:06:ce:2a:16:59:
         64:e9:30:b2:a2:73:24:56:2d:96:60:3e:d4:a8:4b:78:21:cd:
         db:87:e1:15:b2:fb:cd:72:c3:87:c6:18:96:0c:01:a9:a7:b2:
         06:49:51:b7:bb:75:2e:3f:ea:66:ab:28:21:59:c9:0f:1f:8b:
         ee:93:03:f2:f6:71:1a:55:34:1f:f6:22:8e:76:d9:f3:71:c7:
         45:71:01:8f:57:95:b3:e6:87:22:4d:61:cc:47:a9:c8:dd:ff:
         89:07:19:22:03:0c:11:0e:00:ca:3d:98:30:4d:46:2c:dc:39:
         17:3f:67:5a:8d:ac:94:09:7c:f9:87:4e:a0:c8:b2:c0:b5:7b:
         bc:46:bf:04:79:d2:f4:26:8e:21:ad:5e:d7:7b:32:8a:5a:14:
         66:96:d4:9d:f6:85:0a:41:df:0c:ee:11:6f:d1:54:36:6d:2b:
         71:32:bc:b5:de:d8:98:c0:2d:8d:89:ca:cb:dd:76:6f:98:4f:
         86:ed:76:85:19:23:29:e5:bd:25:29:68:44:ef:75:97:87:55:
         ef:61:03:f2:38:44:bc:e6:5a:b6:95:e0:5c:9d:ae:bf:44:77:
         75:6b:64:01:74:18:8e:c6:6d:43:ce:3e:8d:62:34:4c:68:d6:
         c5:90:75:a4:9c:2c:8e:da:31:1c:42:0e:b9:fb:a3:03:6d:85:
         cb:33:de:11:a3:16:03:81:7c:fd:34:63:e8:54:ce:0c:18:56:
         aa:8c:b1:a3:6e:33:64:47

创建服务器证书

现在让我们使用上面创建的根证书,创建一个我们可以使用的 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: 16405080066384587582 (0xe3aa8d670cb1eb3e)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Oct 16 11:55:06 2021 GMT
            Not After : Oct 11 11:55:06 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:be:8a:1e:dd:ea:c1:5f:1a:7c:a0:31:1c:52:61:
                    19:0e:35:48:48:f7:49:68:e1:0e:05:6e:36:c2:2d:
                    19:06:c6:3d:5f:08:b5:36:f6:77:a1:f6:e0:2f:f0:
                    1f:88:b2:3b:f3:8a:c0:b9:7a:58:aa:17:b1:6d:6f:
                    25:15:ce:93:bb:e5:d1:91:f7:da:56:ce:d7:0a:21:
                    6a:d6:02:26:c7:50:11:41:d8:49:28:13:ff:32:20:
                    3a:75:6c:74:e2:a0:74:a1:b3:6f:2e:a5:46:85:19:
                    66:6c:68:b2:ea:fe:e1:4a:ec:c2:dd:20:41:2d:0d:
                    02:01:61:e0:d1:99:35:6f:d6:3a:07:e0:a4:2e:74:
                    a0:ef:8e:53:2f:9c:16:4a:2d:df:21:f4:5b:a6:a8:
                    eb:a9:3d:08:36:ca:08:8d:d4:5d:9e:ef:bb:a1:08:
                    70:96:7f:43:fb:04:3c:f5:26:4c:eb:bc:b5:63:fa:
                    b5:34:05:95:90:9d:f5:b3:19:45:b5:35:56:49:1c:
                    a6:b3:c9:78:ba:4e:f0:a8:86:3e:50:19:06:dc:b2:
                    7b:6a:09:c4:f2:90:7e:3f:21:10:db:31:43:30:aa:
                    52:cb:1f:d7:ad:2f:cb:d2:11:6b:64:6c:46:b3:3f:
                    8e:fc:79:da:36:ce:86:8a:4c:7f:6c:3b:76:a1:e4:
                    fb:fe:82:3a:d3:9f:7b:2b:92:80:d5:84:d1:49:4c:
                    43:7e:29:3e:c1:ba:6e:95:30:80:04:4b:eb:cb:1d:
                    8b:55:2e:f3:2f:e5:27:68:52:94:47:04:be:e2:91:
                    e0:5a:28:47:e4:47:1c:32:41:d9:f0:d7:52:76:78:
                    f7:8b:46:b3:24:4e:e1:27:fd:e6:1d:66:f6:29:15:
                    79:f1:b6:b0:80:c2:76:1a:99:b6:f4:f0:a5:8b:f0:
                    3f:e8:0b:cb:70:3f:dd:0d:57:01:bd:19:21:d2:3b:
                    ff:44:66:79:d1:a5:f3:a0:6d:c6:b6:f5:c2:76:7c:
                    c9:3e:db:10:79:b0:83:39:f7:e7:7e:44:6c:2c:29:
                    42:77:71:68:3f:5d:9a:56:02:84:a8:e9:7b:36:53:
                    5f:a6:a0:20:2e:50:2c:e7:ff:1c:4d:94:6c:aa:2c:
                    ab:a3:ed:ed:c5:60:74:7a:00:50:b9:f5:d6:ff:43:
                    64:cc:84:d7:b4:96:69:fc:e1:56:50:93:58:14:cc:
                    40:86:e2:e4:f0:a0:95:64:98:8c:1d:2e:9b:2e:36:
                    11:19:62:96:4d:bc:47:72:95:89:d5:a9:64:5c:48:
                    cc:10:2a:d7:94:ab:57:19:b9:b9:46:4a:de:e1:ad:
                    19:93:9c:de:a6:09:1d:26:64:c9:f5:96:eb:ad:94:
                    b7:29:45
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2

            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
         28:44:f7:5a:e5:54:e2:71:a0:47:c1:76:11:27:0f:bc:fd:93:
         06:a7:03:19:f7:36:33:80:f8:20:7b:41:34:21:09:43:ea:a5:
         0c:f9:0d:f7:91:36:61:d4:4a:20:5f:32:b3:87:39:81:f8:26:
         4c:89:21:b5:dd:c3:bd:fc:6e:63:c7:2c:8a:77:f4:c1:a5:b3:
         52:bd:4a:18:52:9b:4b:62:1a:f4:62:3e:0e:05:83:5e:3e:e7:
         2e:69:f9:6a:0e:4f:73:b1:93:c1:de:ca:8f:d3:a5:81:f9:41:
         6b:86:60:46:26:af:71:ca:ca:47:d0:91:3f:b7:22:f2:47:13:
         f7:44:4e:ce:47:be:1a:17:39:d4:b1:de:d7:0e:c2:10:0f:39:
         5b:74:c4:21:c4:06:a7:6a:33:3b:83:3f:5d:a5:89:e9:0d:61:
         cd:3a:35:7e:24:79:21:d0:3a:8b:d7:45:44:97:88:71:04:7f:
         5a:a4:0c:81:d5:b6:06:6e:7e:a2:96:97:ce:51:03:98:4f:ef:
         b5:f8:55:eb:77:ad:37:36:88:ea:e8:95:28:a5:39:2c:83:b5:
         3b:2b:c5:a8:31:2a:27:22:0e:34:73:82:0d:06:ce:2a:16:59:
         64:e9:30:b2:a2:73:24:56:2d:96:60:3e:d4:a8:4b:78:21:cd:
         db:87:e1:15:b2:fb:cd:72:c3:87:c6:18:96:0c:01:a9:a7:b2:
         06:49:51:b7:bb:75:2e:3f:ea:66:ab:28:21:59:c9:0f:1f:8b:
         ee:93:03:f2:f6:71:1a:55:34:1f:f6:22:8e:76:d9:f3:71:c7:
         45:71:01:8f:57:95:b3:e6:87:22:4d:61:cc:47:a9:c8:dd:ff:
         89:07:19:22:03:0c:11:0e:00:ca:3d:98:30:4d:46:2c:dc:39:
         17:3f:67:5a:8d:ac:94:09:7c:f9:87:4e:a0:c8:b2:c0:b5:7b:
         bc:46:bf:04:79:d2:f4:26:8e:21:ad:5e:d7:7b:32:8a:5a:14:
         66:96:d4:9d:f6:85:0a:41:df:0c:ee:11:6f:d1:54:36:6d:2b:
         71:32:bc:b5:de:d8:98:c0:2d:8d:89:ca:cb:dd:76:6f:98:4f:
         86:ed:76:85:19:23:29:e5:bd:25:29:68:44:ef:75:97:87:55:
         ef:61:03:f2:38:44:bc:e6:5a:b6:95:e0:5c:9d:ae:bf:44:77:
         75:6b:64:01:74:18:8e:c6:6d:43:ce:3e:8d:62:34:4c:68:d6:
         c5:90:75:a4:9c:2c:8e:da:31:1c:42:0e:b9:fb:a3:03:6d:85:
         cb:33:de:11:a3:16:03:81:7c:fd:34:63:e8:54:ce:0c:18:56:
         aa:8c:b1:a3:6e:33:64:47

重要

一定要确保生成的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: Oct 16 11:55:06 2021 GMT
            Not After : Oct 26 11:55:06 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: 
                7B:D2:76:BA:9E:CA:B2:2B:85:3C:47:E6:4A:F2:29:F5:51:6C:BD:D4
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:E3:AA:8D:67:0C:B1:EB:3E

            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 Oct 26 11:55:06 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: Oct 16 11:55:06 2021 GMT
            Not After : Oct 26 11:55:06 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:bc:0f:07:e7:25:58:a0:15:a7:bf:be:eb:73:fe:
                    0d:34:ac:65:a9:38:d6:a0:2b:4d:6c:ac:87:ce:f3:
                    cb:f4:db:b0:0e:a0:0d:29:ed:d5:1e:81:79:6d:b3:
                    0b:ce:06:c3:2c:12:63:a7:e4:91:6c:95:3d:0c:fd:
                    ad:4a:fb:b4:87:7e:a2:c6:7c:b1:5e:85:53:2e:ed:
                    14:26:7c:3a:54:39:6a:8c:bc:7a:ec:0a:14:ca:29:
                    68:da:f4:1d:69:7a:a8:6f:33:03:2e:88:96:7e:53:
                    b8:12:d6:d5:68:f5:e0:33:3f:10:dc:4a:4c:64:5f:
                    47:37:fd:7d:a5:bd:e5:1a:8b:60:0d:9a:c0:e7:16:
                    53:2a:6e:31:b8:99:be:eb:8b:27:25:15:e9:b5:5f:
                    e1:e5:81:29:bd:f8:26:62:c5:c3:8d:16:cf:3a:3f:
                    27:9c:05:5d:bc:4f:5d:8f:b0:8d:5a:14:89:07:10:
                    4f:5c:59:e9:c1:85:e0:4e:71:62:89:df:07:c1:dd:
                    cc:f9:77:c7:90:f5:fc:21:a5:81:84:d1:64:c0:e6:
                    39:60:06:db:69:48:cd:1e:e6:f3:91:30:2b:56:4b:
                    cf:02:d2:dc:c1:56:5f:a2:c1:0d:c4:b4:88:31:1e:
                    d5:02:d0:9e:fd:eb:31:79:f4:0a:52:ad:0c:5c:ad:
                    10:ef
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                QiYuTech Server Certificate
            X509v3 Subject Key Identifier: 
                7B:D2:76:BA:9E:CA:B2:2B:85:3C:47:E6:4A:F2:29:F5:51:6C:BD:D4
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:E3:AA:8D:67:0C:B1:EB:3E

            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
         6d:b8:37:f7:36:30:5c:37:6f:3f:b6:07:72:9a:de:5d:9e:e3:
         bb:c4:13:98:43:1b:7e:1a:de:a5:0e:01:c8:8d:fe:c6:dc:87:
         47:3c:14:e0:cf:7d:0b:76:06:8f:75:e0:b8:02:83:a3:0c:47:
         09:e2:99:a2:ca:bf:94:2d:f7:c9:c8:cc:3a:ed:a1:41:5d:ed:
         47:ae:62:f7:f5:49:27:55:d4:4d:5c:c5:d3:97:50:26:82:3d:
         1c:5a:7e:9b:3f:db:ae:9d:32:a2:50:91:d1:87:06:3d:9b:09:
         7b:8c:28:84:87:2d:f4:4a:fc:d4:2a:49:82:5d:12:37:bf:a8:
         b3:f1:b6:25:0b:9f:7d:50:eb:d6:b4:d3:f7:02:40:9c:63:a0:
         b0:99:18:98:e0:26:1e:23:bc:24:29:f9:ab:96:8d:13:fb:15:
         ef:77:59:cc:d7:95:25:fd:91:1a:7b:e3:5a:ba:44:ae:06:6c:
         dd:e2:ed:0e:09:06:48:ae:47:46:84:c6:e6:1c:98:e1:f8:32:
         a8:52:bc:81:8a:fd:c4:68:3b:c2:90:16:a5:1f:62:47:d1:2a:
         28:8e:8f:59:be:3a:06:26:5c:1a:1a:7b:44:83:bc:57:1d:55:
         58:b6:c1:c8:19:ab:b8:f4:2c:d3:b5:63:45:d7:ad:ef:8c:75:
         da:cb:7e:9f:9b:27:f1:2d:7d:d1:88:6a:39:53:fe:b0:57:49:
         57:6e:4f:23:b5:fe:23:46:bb:76:65:e9:2d:7d:10:28:f9:4b:
         1b:54:63:d0:a3:f0:2e:30:b9:7e:4e:3c:4b:78:e6:38:99:41:
         5a:e4:55:7d:80:89:2d:71:cf:f1:bf:f2:b5:44:37:b8:c3:dc:
         69:5a:07:08:74:65:91:5b:a3:cf:c4:ed:85:88:f1:7d:8b:ec:
         26:cd:37:c2:16:16:98:3a:41:7a:fd:a9:1c:a2:19:78:fd:a4:
         4b:cf:24:f5:5e:52:68:ea:00:fa:97:71:e5:d1:60:64:fc:49:
         5d:28:46:90:b0:76:21:73:ff:72:99:e4:01:f2:54:56:d6:23:
         9d:b2:00:13:c7:02:da:4a:f3:cf:41:6f:71:17:e5:42:66:bc:
         08:bd:85:3d:73:d9:1d:f1:e0:1b:22:2c:e2:bb:c6:d8:2c:b3:
         ab:05:28:df:54:68:a2:18:b7:56:1e:8d:55:ea:5d:23:74:4e:
         81:3d:ff:67:aa:1d:fc:a1:bb:9c:3f:d4:6f:41:4a:b3:52:bb:
         10:1c:48:96:5b:83:e0:7f:67:62:bd:7a:fc:f1:56:1b:b7:f9:
         eb:0f:0e:69:99:90:b3:91:5c:64:1d:e1:26:f4:01:76:ed:f4:
         da:62:26:ee:47:b9:0e:35

警告

需要确保 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: Oct 16 11:55:06 2021 GMT
            Not After : Oct 26 11:55:06 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: 
                60:35:F5:56:8A:1C:1D:B9:3E:18:50:29:A6:A3:4F:50:2D:59:9E:70
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2

            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 Oct 26 11:55:06 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: Oct 16 11:55:06 2021 GMT
            Not After : Oct 26 11:55:06 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:e5:d4:f7:80:69:72:f6:b1:a3:a6:44:d1:b7:e3:
                    42:50:70:48:ae:49:0c:a8:00:0c:b4:09:78:ee:9d:
                    31:30:2b:72:40:26:c1:7d:d6:5e:cf:31:6d:27:29:
                    21:c6:d5:ca:d3:e9:27:9a:30:14:9e:15:44:68:19:
                    39:11:b5:ce:28:dc:21:2b:38:93:f3:74:ed:7e:05:
                    e7:42:2d:d2:ea:bf:4c:94:21:85:73:13:f9:94:4c:
                    18:b9:62:03:c4:5e:35:f9:b2:51:27:0d:45:54:61:
                    ea:14:41:b4:45:bb:d2:f1:a3:52:3a:67:bf:57:ed:
                    83:24:ec:34:37:e1:8d:6d:ff:e8:6e:d7:54:32:e7:
                    16:d4:48:5a:c0:93:1c:bd:d4:a2:b7:8a:13:c2:97:
                    a3:84:06:39:40:90:15:ca:a1:9c:16:87:8c:8d:e1:
                    48:5c:7b:ae:44:79:75:cf:d4:fd:1e:f0:5d:58:b0:
                    74:23:9f:a7:20:13:4d:d0:5a:c4:e5:1a:80:e3:98:
                    b5:13:a1:75:34:c9:46:f7:1b:1e:e3:35:9f:78:f6:
                    e1:38:a4:ae:f6:fe:61:c3:cd:75:17:f0:da:6d:4e:
                    09:a9:78:3d:fe:5b:60:2c:27:66:83:5f:3c:93:e9:
                    bb:2e:10:34:fd:d4:e2:ac:42:6c:bc:03:69:b0:ba:
                    44:f9
                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: 
                60:35:F5:56:8A:1C:1D:B9:3E:18:50:29:A6:A3:4F:50:2D:59:9E:70
            X509v3 Authority Key Identifier: 
                keyid:74:E3:C9:EC:55:A9:73:2D:B1:5C:AD:47:73:D5:68:A2:67:F5:FB:D2

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

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