如何在 Linux 上生成自签名 SSL 证书
SSL 是一种用于加密和验证网络上数据(通常在服务器和客户端之间)的协议。 SSL 协议及其后继者 TLS 使用基于两个密钥的非对称加密:私有密钥和公共密钥。 SSL 证书提供加密连接并创建信任环境,因为它证明我们正在连接的网站实际上是我们想要的,并且没有恶意方试图冒充它。有效的 SSL 证书由 CA(证书颁发机构)发布,但也可以自行生成。自签名 SSL 证书虽然仍提供加密,但不提供任何信任,因为所有者和颁发者是同一实体/个人。尽管如此,它们在某些情况下可能很有用:例如,用于测试或内部使用。在本教程中,我们将了解如何使用 Linux 上的 OpenSSL 工具包生成自签名 SSL 证书和密钥对,如何读取证书,以及如何从中提取公钥。
在本教程中您将学习:
如何在 Linux 上生成自签名 SSL 证书和密钥对
如何读取SSL证书的内容
如何从证书中提取公钥
使用的软件要求和约定
安装 OpenSSL 工具包
OpenSSL 工具包可在最常用的 Linux 发行版的官方存储库中找到。它包含一组实用程序和库,为各种类型的协议和算法提供支持。该工具包作为其核心包的依赖项已安装在您的系统上,有非常高的变化;但是,要显式安装它,我们可以使用我们选择的发行版的包管理器。在 Fedora 和 Red Hat 系列的其他发行版上,我们使用 dnf:
$ sudo dnf install openssl
在 Debian、Ubuntu 及其衍生产品上,我们可以使用 apt 包装器:
$ sudo apt install openssl
如果 Archlinux 是我们的日常驱动程序,我们可以使用 pacman 包管理器安装 OpenSSL 工具包。该包维护在“核心”存储库中:
$ sudo pacman -Sy openssl
安装工具包后,我们可以看到如何使用它来生成自签名证书。
生成自签名证书
为了生成自签名证书,我们可以使用 OpenSSL 工具包中包含的众多实用程序之一:req
。该工具的描述如下:
req 命令主要创建和处理 PKCS#10 格式的证书请求。它可以 例如,另外创建自签名证书用作根 CA。
要生成证书和私钥,我们需要使用 -newkey
选项运行 req
。让我们看一下该命令的示例。我们稍后再讨论:
$ openssl req -newkey rsa:4096 -x509 -sha512 -days 365 -nodes -out certificate.pem -keyout privatekey.pem
让我们分析一下上面示例中使用的各种选项。首先,我们使用 -newkey
选项调用“req”:它用于创建新的证书请求和私钥。它需要一个参数,我们可以用它来指定我们想要生成的密钥的类型及其大小。在示例中,我们使用:rsa:4096
,因此创建了 4096 位的 RSA 密钥。如果我们省略密钥大小,则使用默认密钥 (2048)。
我们使用的第二个选项是-x509
。此选项的作用只是修改程序的行为,以便创建自签名证书而不是证书请求。两者有什么区别?在需要安装证书的服务器上创建证书请求并将其发送到颁发证书的证书颁发机构。正如我们已经提到的,自签名证书由同一个人或实体拥有和提供。该过程不涉及证书颁发机构:这就是此类证书不提供信任的原因。
使用 -sha512
我们指定了消息摘要来签署请求/证书。默认摘要再次在 OpenSSL 配置文件中的 default_md
键下指定,并且为 sha256
。要获取所有可用摘要的列表,我们可以运行:
$ openssl list --digest-commands
我们应该获得类似于以下内容的结果:
blake2b512 blake2s256 gost md2
md4 md5 rmd160 sha1
sha224 sha256 sha3-224 sha3-256
sha3-384 sha3-512 sha384 sha512
sha512-224 sha512-256 shake128 shake256
sm3
由于我们生成的是自签名证书,因此我们可以自行决定其有效期限。有效期以天表示(默认30天);天数作为参数传递给 -days
选项。在这种情况下,我们计算了一整年的证书价值。
使用 -nodes
选项,我们指定不想加密生成的私钥。加密私钥无疑是有用的:这可以作为一种安全措施,以防有人窃取它,因为要使用它,应该提供密码。举个例子,如果我们在 Apache 中使用私钥,则每次重新启动守护进程时都必须提供密码来解密它。在这种情况下,由于我们正在生成一个自签名证书,我们将使用它进行测试,因此我们可以避免加密私钥。
最后,我们使用 -out
和 -keyout
选项分别指定要写入证书和密钥的文件名。在这种情况下,证书将保存到 certificate.pem
文件中,私钥将保存到 privatekey.pem
文件中。为什么我们使用“.pem”作为文件名后缀?这是因为证书和密钥都将以 PEM 格式创建。 PEM 代表“隐私增强邮件”:它基本上是一个包含 base64 格式数据的容器。
提供证书信息
一旦我们运行命令生成证书,系统将提示我们提供一系列信息。其中:
代表国家/地区名称的两个字母(例如 US)
完整的州或省名称(例如加利福尼亚州)
城市名称(例如洛杉矶)
组织或公司名称(公司的法定名称)
服务器的完全限定名称
Generating a RSA private key
.............................................++++
...........................++++
writing new private key to 'privatekey.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:California
Locality Name (eg, city) [Default City]:Los Angeles
Organization Name (eg, company) [Default Company Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.fqdn.com
Email Address []:
阅读证书内容
在该过程结束时,我们应该在当前工作目录中找到两个创建的文件(certificate.pem 和 privatekey.pem)。如果我们查看我们的证书文件,我们应该找到类似于以下内容的内容:
-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIUYqXQl7Y5G6BAXpQ32GWfekpTEJcwDQYJKoZIhvcNAQEN
BQAwTzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAcM
C0xvcyBBbmdlbGVzMRUwEwYDVQQDDAx3d3cuZnFkbi5jb20wHhcNMjIwMzIwMjI0
NTU4WhcNMjMwMzIwMjI0NTU4WjBPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
aWZvcm5pYTEUMBIGA1UEBwwLTG9zIEFuZ2VsZXMxFTATBgNVBAMMDHd3dy5mcWRu
LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALHf3gnGCATAUEKc
xgq3mmwM+wI9HV3SaYEnHgNJnt47FgFHcLWmzMRARrx1ofrwWSYUCGNDidit6FHv
fHDyVoH344G8tuyU5YhzddmmphoGpU7jdwbQvtSqcJxOU84KSmwoMp/sIb+iNfSA
rcNj1mTMHJJmePwCloDT2/7tuMvBlhfG5JHk5mSwi2GpSi06VqkzKeRBzaJTKEVq
vUJNOcBJBCJPhj+I32J3SeJ6YnCfvLyaBzVBR0T+2umGXDTU0KwSnoCg3Swslfma
GKDNLzvUerqwxEEUjaKjzdtzclvVJ86xVGI1TiVPdngullHCBdys5PxXabxhv1mF
FRgxCXjyctVeEcTx+SIDoxMWVTZFXFbaGUbeXFYEXbm0dzYOj0Y+rbIxvBVGfLDG
qngUuIOE3iiaOA/h/V0MuIhFVXg0tO4ZIsN5sZAMpGuLduB5W2soNpb7uRVneEyP
VIYwzYT8i4YJMVXCMwQKHQFQbeU2QKTsx0aXnR7O84CUQxCah86FJpzNP5jMjTht
82X08rKGBp5G85hyUQEyvZrtQ9etFHDVdDvfuuFFQf0vXwDUpS7WHOOcK1+M0ztr
lxk/vg4qazw7vwXSRD93a1VgnsGAXV8oxKuzUzUCj96JJvjdnd56h3B9ERShEpZx
Ua1lgB8sTDG8l3kTpggsfXWHgLTRAgMBAAGjUzBRMB0GA1UdDgQWBBSnylKfTIQJ
PNbq+z50Ao0HfrpfMjAfBgNVHSMEGDAWgBSnylKfTIQJPNbq+z50Ao0HfrpfMjAP
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4ICAQBDISi+LunywZWapJFc
XbPll/BKbsJNX+4gmMOysFr0QRtDfrXGKN57DlZvfYlkNeBdXi6urGfWuuERbmqo
IN2KmYbCTCG5RhfiVvS9MvbQOtItq+tJCIVD2YznblAniU2qy3tquGVLGRSR2SuB
X/r8a6NGZ8SzxpeUgQEKYStiIVjkAUrLzn0UXy7ul7pTghy5w4AgiC0AwecnUWwl
Dyb+TXadAD0PfHvHMJvMTlfFtVGJgDFPPPAocQ1BHmzxsY01QcXnOfUXGwoldrp5
H5Yf+kbxru6TMPoC8Q0oZqPXX5k4SmOP3npaFQ3q6Zti6Z0EXY1Tq9h0pBTJMXzK
B4RX7owrX3k7H2DPZjColyFzjmmdTT75y9CGrDwoKk6RQFDO5/aSfkE3y+KFbQq/
rib/BymCzoYl/4E5LA7SStBk0pTv0qRJEqOhzNdOqkq+xWAEC4JN8a63MY1Fxaii
cDgEeYLtdSpfEyB2AsmYDa+hF9lmYP3pcInCsU3iSuYpn8g09iHtCWAvyvcO2tyP
JT+Gi6h38jAIAziUI3kXVTbc9tvVfDRlF4mK66z1Iz7loMP4TMSObW35mf200Zvt
HqbrhlF8KWMY/IxCM0LNkxQXEIoW3yHm3G3OHoV184XTyW0CKFK18dC8SuYc24cX
kLAgdGVMwED+WtoF6hPKfznmIA==
-----END CERTIFICATE-----
正如我们已经说过的,证书是 PEM 格式的,因此要读取其内容,我们可以发出以下命令:
$ openssl x509 -noout -in certificate.pem -text
x509
实用程序用于显示和签署证书。在本例中,我们使用 -noout
选项调用它,以避免在输出中包含证书的编码版本,-in
指定包含证书的文件用作输入(在本例中为certificate.pem)和-text
以文本形式打印证书的输出。在本例中,我们只想在标准输出上可视化证书内容;要将其保存到文件中,我们可以使用 -out
选项并提供目标文件名作为其参数,或者简单地使用 shell 重定向。这是命令的输出:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0f:d2:5a:6c:99:74:37:2e:4b:3a:86:a3:d3:61:95:6a:03:85:04:71
Signature Algorithm: sha512WithRSAEncryption
Issuer: C = US, ST = California, L = Los Angeles, CN = www.fqdn.com
Validity
Not Before: Mar 21 11:03:48 2022 GMT
Not After : Mar 21 11:03:48 2023 GMT
Subject: C = US, ST = California, L = Los Angeles, CN = www.fqdn.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:b9:6a:fa:50:18:bb:3d:26:80:ef:a4:08:1d:8c:
11:14:c5:5e:81:73:d3:4d:32:b2:86:9a:c2:04:53:
44:74:b8:34:ca:99:42:71:01:30:ae:f3:ef:59:83:
fb:bc:8d:e6:ca:b4:7b:6c:82:fe:f5:19:0a:76:26:
d6:de:9e:33:62:52:74:a9:63:f9:09:f8:41:4f:9c:
68:0b:23:4c:62:61:ad:59:8e:f5:bc:e8:42:b3:1a:
3d:4e:19:6b:4d:20:b3:42:a5:ae:a1:6f:14:7e:c8:
d5:e9:1d:ac:6a:26:5d:ef:40:58:55:b7:21:a6:0d:
fb:94:76:a9:95:67:59:c4:2e:5a:42:0f:25:fa:b3:
c9:67:38:f2:2f:3b:84:62:d0:6c:1f:b1:ea:58:8b:
12:35:13:45:47:01:d9:66:04:b0:ed:39:cd:e7:ed:
17:a1:ea:bd:27:89:e7:b9:26:96:82:d1:d3:d8:75:
82:f6:f6:07:31:6b:d7:7a:59:87:24:61:0a:3b:29:
97:49:43:ef:26:a1:9e:98:f2:ff:ea:49:01:a0:bf:
9b:45:69:b1:b6:c2:2e:de:e5:e0:43:09:a3:82:46:
cf:64:84:d2:eb:dd:7d:08:92:f3:89:e3:51:97:25:
23:be:62:c6:f8:ff:b4:b5:ae:78:a9:ff:81:a8:76:
7b:79:c3:05:55:f0:ce:11:b4:38:00:ef:1f:bd:58:
bd:cf:2e:74:ce:30:38:94:d4:64:ab:fc:a9:98:24:
18:dc:e1:10:f8:67:b5:ef:b8:ec:81:60:5d:7a:f3:
1e:01:fe:87:2b:55:71:01:0c:7f:fc:4b:9a:3a:33:
3e:c8:28:33:e6:ad:18:ef:1d:98:33:1e:89:fb:4c:
0b:e8:d2:5a:9d:53:70:2a:12:29:ed:45:79:89:55:
30:4a:f6:5f:41:98:8d:d6:37:d5:a0:02:8a:75:3e:
07:c4:67:45:56:85:c9:8e:5f:25:fb:77:0c:48:94:
29:07:95:f0:07:39:fc:cd:09:02:9b:07:3d:11:8b:
62:4e:e8:5e:fc:c6:a0:41:aa:20:a1:c9:44:63:eb:
fd:db:4b:7c:62:1b:b1:46:93:08:37:30:d9:11:84:
0e:ad:97:0b:20:29:41:ba:89:b6:36:84:7d:b6:59:
47:06:86:5a:d6:04:48:b6:87:c8:9c:c7:c3:02:02:
6e:51:ea:11:46:db:d5:b1:9e:e9:75:46:26:5f:9f:
15:92:bc:9c:4b:e2:4d:1b:bc:d5:1b:2e:b0:56:71:
fb:4a:20:91:11:8b:31:ae:55:83:e7:e5:96:61:9f:
4d:46:08:02:d3:20:b6:b2:f2:ad:72:78:73:27:a8:
36:92:6f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
62:B1:F4:A8:E1:76:4E:DA:23:67:2D:4B:48:BC:DE:63:4D:7A:15:CB
X509v3 Authority Key Identifier:
keyid:62:B1:F4:A8:E1:76:4E:DA:23:67:2D:4B:48:BC:DE:63:4D:7A:15:CB
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha512WithRSAEncryption
1d:67:0f:7e:5e:0f:13:7b:ce:80:cd:18:d7:01:ce:65:b7:b0:
c7:6f:21:1c:41:1c:8b:d8:d1:53:1d:2b:4c:57:2a:60:30:62:
d9:d1:1f:6d:ff:8e:56:d0:8b:0b:b1:83:ee:a9:b4:d6:84:cd:
ca:c6:9c:f8:84:7c:47:7b:c6:08:6d:b2:20:9b:88:02:4b:5c:
30:32:17:2d:37:a6:a3:de:24:14:fb:8c:d1:82:1d:bc:4e:2e:
52:a4:87:8d:98:fc:4b:b1:e2:ac:2a:ed:f9:e9:21:36:bc:a0:
90:f5:a3:f7:f5:5a:e7:5e:aa:a7:58:b6:97:b5:b0:73:f5:03:
14:91:b1:fe:41:49:05:17:e4:fb:0d:be:07:38:86:9d:b4:5a:
02:c7:91:e9:c0:c1:53:59:e5:3f:60:2c:cb:fe:15:94:30:67:
f2:a9:1a:d9:a1:71:49:43:a9:45:cb:97:14:7f:e7:6a:9d:19:
41:95:db:01:d9:ba:fc:5f:51:43:5b:cd:14:ff:4b:b0:63:7c:
6b:76:54:86:b9:c6:a2:92:16:7c:22:09:eb:b6:4c:4a:85:40:
e8:9f:fb:0a:40:ff:2d:c6:75:06:f9:67:ba:2e:63:4e:25:0e:
bb:0d:e0:d4:05:9c:ce:c5:b4:36:19:58:db:87:f6:af:1c:4d:
45:2b:de:ec:f2:9a:4a:e2:0e:63:5f:bb:fa:15:20:35:10:93:
ce:23:35:33:16:f8:61:c0:6e:48:12:55:29:d2:5a:41:d1:9a:
47:ef:d9:fd:54:91:15:a0:4b:83:b2:f6:78:1d:98:e5:71:03:
2a:4b:eb:db:49:78:61:85:16:71:ea:a6:ed:8e:64:98:00:e0:
73:9a:66:4b:4c:30:b7:d3:a7:0c:bb:af:09:cc:5c:c1:7a:ef:
9c:42:19:1b:95:e4:25:37:ba:cf:db:74:1f:cd:a3:a9:84:11:
39:27:62:59:60:7e:b4:82:e6:a0:33:bd:e9:32:6a:86:61:86:
cf:dc:1e:f0:93:b7:42:7d:92:5d:39:df:c2:60:1b:5a:b4:0d:
5e:20:92:7a:d4:09:4f:2e:87:81:34:bb:aa:75:97:b1:f8:23:
bd:ff:63:12:fa:d2:3b:8b:8c:74:7c:1b:16:2b:0a:5b:94:69:
22:58:45:d2:0f:75:16:26:60:d9:81:7b:e9:83:79:26:b0:c0:
32:ca:46:80:07:eb:df:8e:00:c8:fa:17:a5:e1:e2:24:cc:2c:
a6:13:a2:0d:35:d6:5a:1a:d1:5e:a2:d7:83:69:32:73:af:77:
ed:6a:13:7b:60:d2:2c:78:f2:0d:4b:04:ec:c6:57:38:50:ee:
a4:ab:c0:b0:24:4b:01:70
从证书中提取公钥
正如我们所看到的,SSL/TLS 基于非对称加密以及私钥和公钥的使用。私钥必须在服务器上保持安全,而公钥则与证书一起发送到客户端。我们如何提取其中包含的公钥?嗯,这是一个非常简单的操作。要完成此任务,我们必须再次使用 -x509
命令。要从我们在本教程中生成的证书中提取公钥,我们将运行:
$ openssl x509 -pubkey -noout -in certificate.pem
我们调用了 x509,这次使用 -pubkey
选项,这使得证书公钥以 PEM 格式打印:
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuWr6UBi7PSaA76QIHYwR
FMVegXPTTTKyhprCBFNEdLg0yplCcQEwrvPvWYP7vI3myrR7bIL+9RkKdibW3p4z
YlJ0qWP5CfhBT5xoCyNMYmGtWY71vOhCsxo9ThlrTSCzQqWuoW8UfsjV6R2saiZd
70BYVbchpg37lHaplWdZxC5aQg8l+rPJZzjyLzuEYtBsH7HqWIsSNRNFRwHZZgSw
7TnN5+0Xoeq9J4nnuSaWgtHT2HWC9vYHMWvXelmHJGEKOymXSUPvJqGemPL/6kkB
oL+bRWmxtsIu3uXgQwmjgkbPZITS6919CJLzieNRlyUjvmLG+P+0ta54qf+BqHZ7
ecMFVfDOEbQ4AO8fvVi9zy50zjA4lNRkq/ypmCQY3OEQ+Ge177jsgWBdevMeAf6H
K1VxAQx//EuaOjM+yCgz5q0Y7x2YMx6J+0wL6NJanVNwKhIp7UV5iVUwSvZfQZiN
1jfVoAKKdT4HxGdFVoXJjl8l+3cMSJQpB5XwBzn8zQkCmwc9EYtiTuhe/MagQaog
oclEY+v920t8YhuxRpMINzDZEYQOrZcLIClBuom2NoR9tllHBoZa1gRItofInMfD
AgJuUeoRRtvVsZ7pdUYmX58VkrycS+JNG7zVGy6wVnH7SiCREYsxrlWD5+WWYZ9N
RggC0yC2svKtcnhzJ6g2km8CAwEAAQ==
-----END PUBLIC KEY-----
结束语
在本教程中,我们学习了如何使用 OpenSSL 工具包和“req”命令生成自签名 SSL 证书。我们了解了如何提供证书信息以及如何设置其有效期(以天为单位)。最后,我们了解了如何读取证书的内容以及如何从中提取 pem 格式的公钥。