最新、最全、最好的自签名证书教程(开箱即用)¶
虽然我们不经常创建证书(尤其是根证书,申请 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
警告
很多人生成的证书无法使用通常都是因为没有附带 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