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

虽然我们不经常创建证书(尤其是根证书,申请 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: 13242150775799987933 (0xb7c591f87db8bedd)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Jun  4 14:30:53 2021 GMT
            Not After : May 30 14:30:53 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:e3:a5:54:47:76:63:12:2a:b9:47:53:2e:7b:1a:
                    d2:f5:8b:5f:f6:2f:41:63:99:36:9c:32:e5:14:26:
                    f3:bd:80:83:fe:96:20:29:7e:3c:1a:92:9b:61:a3:
                    a6:ad:32:6d:58:f7:84:d5:86:5a:92:74:03:bd:6e:
                    01:81:4a:7d:36:d4:98:81:63:d5:ff:f5:80:26:cb:
                    79:7c:8b:a6:02:9d:5d:36:72:1b:d9:92:0e:a2:28:
                    12:ac:fe:c8:00:e9:1e:b6:ac:cb:7c:74:56:3e:3e:
                    f3:55:f5:b4:23:80:22:95:75:11:2c:ab:2d:74:fb:
                    31:ed:9c:be:4d:8a:75:b1:9c:77:d6:a3:43:7e:04:
                    8f:b7:95:36:22:3b:4c:af:64:29:02:b1:8e:b4:9f:
                    6a:21:58:45:01:de:79:03:74:2b:b8:b7:de:60:d0:
                    56:ca:db:b9:db:f5:9b:00:8d:d1:53:fa:90:ba:67:
                    fd:6b:7b:76:f1:16:a8:dc:9c:7c:ec:36:34:05:87:
                    5d:d1:f2:61:ea:56:3b:ef:1e:d4:f5:46:15:25:10:
                    c0:40:7d:ed:13:70:08:03:14:94:58:06:4b:f7:6c:
                    e6:ef:f7:d0:39:b4:80:f6:5f:f8:a1:67:5b:b6:0d:
                    46:29:e4:93:f7:2c:00:a0:9b:36:d8:e2:2f:f5:4d:
                    5d:4a:7d:c9:1e:c6:c9:09:cb:80:29:ea:53:44:ea:
                    10:d1:91:dc:3a:4e:ae:53:4d:4e:62:87:c7:e2:50:
                    b9:c0:82:93:63:30:07:c1:0b:9a:57:36:13:53:fc:
                    cd:b3:a9:5d:10:6f:bc:69:00:91:f3:fd:4a:05:76:
                    3c:f8:db:48:b9:bb:47:c4:04:e2:38:28:c6:40:d0:
                    67:af:77:e5:d1:a9:c0:3a:7c:c2:da:72:35:b9:f4:
                    57:f0:4f:9d:1c:dd:4e:20:c4:92:28:19:d5:88:dd:
                    aa:27:9e:25:36:f6:4f:e5:3e:6d:8b:cb:a9:57:29:
                    54:91:11:04:ea:28:fb:20:61:bf:f9:67:54:d4:9f:
                    b9:68:98:40:b8:0b:f7:a2:1d:f0:6a:14:39:f2:4a:
                    36:3a:be:3a:10:4e:13:c0:20:3e:30:92:f5:85:39:
                    eb:41:79:cb:48:76:53:2b:a7:bd:ca:92:d8:44:e4:
                    e0:89:9d:b7:5a:49:46:e6:4a:31:d4:97:5a:eb:65:
                    8f:46:dc:ef:86:4c:d2:fe:bf:d4:6c:70:9e:15:35:
                    f0:8c:6a:d6:e2:d7:c8:35:e3:36:44:75:6b:80:56:
                    a2:22:d1:d2:88:15:72:b2:c5:26:76:93:c5:e6:25:
                    3c:0a:2a:22:a1:27:b4:5d:88:d8:10:d9:61:f9:46:
                    38:34:a5
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB

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

创建服务器证书

现在让我们使用上面创建的根证书,创建一个我们可以使用的 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: 13242150775799987933 (0xb7c591f87db8bedd)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=www.qiyutech.tech, O=QiYuTech, ST=BeiJing, C=CN
        Validity
            Not Before: Jun  4 14:30:53 2021 GMT
            Not After : May 30 14:30:53 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:e3:a5:54:47:76:63:12:2a:b9:47:53:2e:7b:1a:
                    d2:f5:8b:5f:f6:2f:41:63:99:36:9c:32:e5:14:26:
                    f3:bd:80:83:fe:96:20:29:7e:3c:1a:92:9b:61:a3:
                    a6:ad:32:6d:58:f7:84:d5:86:5a:92:74:03:bd:6e:
                    01:81:4a:7d:36:d4:98:81:63:d5:ff:f5:80:26:cb:
                    79:7c:8b:a6:02:9d:5d:36:72:1b:d9:92:0e:a2:28:
                    12:ac:fe:c8:00:e9:1e:b6:ac:cb:7c:74:56:3e:3e:
                    f3:55:f5:b4:23:80:22:95:75:11:2c:ab:2d:74:fb:
                    31:ed:9c:be:4d:8a:75:b1:9c:77:d6:a3:43:7e:04:
                    8f:b7:95:36:22:3b:4c:af:64:29:02:b1:8e:b4:9f:
                    6a:21:58:45:01:de:79:03:74:2b:b8:b7:de:60:d0:
                    56:ca:db:b9:db:f5:9b:00:8d:d1:53:fa:90:ba:67:
                    fd:6b:7b:76:f1:16:a8:dc:9c:7c:ec:36:34:05:87:
                    5d:d1:f2:61:ea:56:3b:ef:1e:d4:f5:46:15:25:10:
                    c0:40:7d:ed:13:70:08:03:14:94:58:06:4b:f7:6c:
                    e6:ef:f7:d0:39:b4:80:f6:5f:f8:a1:67:5b:b6:0d:
                    46:29:e4:93:f7:2c:00:a0:9b:36:d8:e2:2f:f5:4d:
                    5d:4a:7d:c9:1e:c6:c9:09:cb:80:29:ea:53:44:ea:
                    10:d1:91:dc:3a:4e:ae:53:4d:4e:62:87:c7:e2:50:
                    b9:c0:82:93:63:30:07:c1:0b:9a:57:36:13:53:fc:
                    cd:b3:a9:5d:10:6f:bc:69:00:91:f3:fd:4a:05:76:
                    3c:f8:db:48:b9:bb:47:c4:04:e2:38:28:c6:40:d0:
                    67:af:77:e5:d1:a9:c0:3a:7c:c2:da:72:35:b9:f4:
                    57:f0:4f:9d:1c:dd:4e:20:c4:92:28:19:d5:88:dd:
                    aa:27:9e:25:36:f6:4f:e5:3e:6d:8b:cb:a9:57:29:
                    54:91:11:04:ea:28:fb:20:61:bf:f9:67:54:d4:9f:
                    b9:68:98:40:b8:0b:f7:a2:1d:f0:6a:14:39:f2:4a:
                    36:3a:be:3a:10:4e:13:c0:20:3e:30:92:f5:85:39:
                    eb:41:79:cb:48:76:53:2b:a7:bd:ca:92:d8:44:e4:
                    e0:89:9d:b7:5a:49:46:e6:4a:31:d4:97:5a:eb:65:
                    8f:46:dc:ef:86:4c:d2:fe:bf:d4:6c:70:9e:15:35:
                    f0:8c:6a:d6:e2:d7:c8:35:e3:36:44:75:6b:80:56:
                    a2:22:d1:d2:88:15:72:b2:c5:26:76:93:c5:e6:25:
                    3c:0a:2a:22:a1:27:b4:5d:88:d8:10:d9:61:f9:46:
                    38:34:a5
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB

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

重要

一定要确保生成的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: Jun  4 14:30:53 2021 GMT
            Not After : Jun 14 14:30:53 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: 
                DF:6D:33:EE:CA:D3:04:CE:C3:8E:08:26:C3:A2:CD:BD:8F:44:30:B9
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:B7:C5:91:F8:7D:B8:BE:DD

            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 Jun 14 14:30:53 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: Jun  4 14:30:53 2021 GMT
            Not After : Jun 14 14:30:53 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:9a:74:2e:31:33:b1:f7:31:26:97:99:95:24:51:
                    e5:d7:3d:16:85:55:f1:02:91:ab:1c:d6:4b:6b:4a:
                    fa:15:a1:86:e3:ab:ca:46:ec:08:09:62:0b:17:5d:
                    15:c1:76:12:57:a4:ec:5f:4b:68:6e:e1:65:76:bf:
                    e7:b7:98:0e:86:a1:3a:5a:73:ff:6c:b7:de:fa:04:
                    13:90:32:db:58:2a:11:62:46:38:ac:e9:d2:b8:af:
                    96:5e:8b:22:34:1e:ac:80:c5:51:d8:91:69:34:e3:
                    88:de:13:37:82:5e:80:a0:74:da:aa:80:2a:94:b1:
                    e5:cf:97:03:9f:16:8e:e2:4f:5e:b2:47:8a:0a:3c:
                    40:61:bf:be:9f:9f:b4:db:c1:ea:bd:ab:3e:ea:fb:
                    02:71:9c:5f:e7:c1:e5:3f:f6:ec:7a:78:b5:50:ab:
                    39:bc:2f:4f:c1:ee:f4:ef:d3:44:3e:2b:9f:77:54:
                    68:50:2c:f8:41:4b:6a:87:39:78:75:40:f5:a2:0f:
                    b8:d9:c3:9e:2d:7f:06:a4:5d:aa:db:46:c6:4b:c0:
                    6c:44:72:61:4a:3f:d6:dc:f9:b2:42:ce:e2:c6:5a:
                    dc:59:62:b1:33:ff:ed:e1:6a:35:52:da:ad:02:87:
                    af:4a:9b:a9:fc:c4:aa:58:a6:e5:60:62:44:20:1f:
                    48:9d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                QiYuTech Server Certificate
            X509v3 Subject Key Identifier: 
                DF:6D:33:EE:CA:D3:04:CE:C3:8E:08:26:C3:A2:CD:BD:8F:44:30:B9
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB
                DirName:/CN=www.qiyutech.tech/O=QiYuTech/ST=BeiJing/C=CN
                serial:B7:C5:91:F8:7D:B8:BE:DD

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

警告

需要确保 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: Jun  4 14:30:53 2021 GMT
            Not After : Jun 14 14:30:53 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: 
                76:18:BA:3E:9E:15:B4:8A:5C:34:03:D8:9C:46:D9:AA:CF:CD:ED:A8
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB

            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 Jun 14 14:30:53 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: Jun  4 14:30:53 2021 GMT
            Not After : Jun 14 14:30:53 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:d2:42:bd:ce:d5:8b:f4:c9:39:2c:76:b4:fc:75:
                    cf:ea:a6:a8:80:8d:0c:f4:27:91:3a:7f:91:8b:57:
                    7a:44:ec:7c:e8:a1:31:e9:1b:8b:14:f3:bc:ab:4e:
                    34:9c:67:81:46:6f:24:df:b2:96:d1:de:1c:10:f3:
                    2e:42:e6:53:32:eb:b4:e2:3b:56:58:df:16:8b:b2:
                    49:f2:de:47:1a:ff:d4:36:28:44:e0:52:24:b1:a4:
                    db:1a:1b:c8:aa:0a:de:fc:d4:57:61:6d:6d:f9:a2:
                    3d:18:b9:bf:0f:83:75:a9:ae:14:e3:02:c1:19:34:
                    7b:f2:47:e3:34:d1:ff:7c:59:67:7c:62:b1:0d:7a:
                    7c:fb:c9:7f:a9:4a:66:13:82:88:63:26:b5:cf:b9:
                    55:84:7c:09:79:88:f5:8c:9a:c2:93:ca:75:8a:80:
                    68:18:9e:93:bb:3b:f6:3e:e5:65:2b:71:f5:1f:78:
                    50:49:f6:65:69:7c:8b:68:23:a5:94:b7:ad:07:9e:
                    90:7d:e1:18:30:c5:b4:81:78:52:cd:ca:38:8d:dc:
                    8f:5a:1f:5e:3e:6b:26:4d:ae:00:41:ec:39:e5:99:
                    ba:c0:cf:a0:65:1e:a8:0f:cf:1e:d4:24:df:77:38:
                    30:19:9f:29:77:20:44:59:54:98:30:0e:5f:7b:a6:
                    1d:ff
                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: 
                76:18:BA:3E:9E:15:B4:8A:5C:34:03:D8:9C:46:D9:AA:CF:CD:ED:A8
            X509v3 Authority Key Identifier: 
                keyid:B9:45:8B:3A:4E:87:2F:BB:BF:8C:CD:9C:59:39:EB:D9:3F:A5:13:EB

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

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