如何创建和签署 SSL/TLS 证书

2025-06-07

如何创建和签署 SSL/TLS 证书

在上一篇文章,我们讨论了数字证书如何帮助身份验证并在 TLS 中提供安全可靠的密钥交换过程。

今天我们将详细学习如何生成证书并由证书颁发机构 (CA) 签署。

在本教程中,我们不会将证书签名请求 (CSR) 提交给真正的 CA。相反,我们将同时扮演两个角色:证书颁发机构 (CA) 和证书申请人。

因此,我们要做的如下:

  1. 第一步,我们将为 CA 生成私钥及其自签名证书。它们稍后将用于签署 CSR。
  2. 第二步,我们将为想要使用 TLS 的 Web 服务器生成私钥及其配对的 CSR。
  3. 最后,我们将使用 CA 的私钥来签署 Web 服务器的 CSR 并取回签署的证书。

为了完成所有这些操作,我们需要openssl安装。如果你使用的是 Mac,它可能已经安装好了。你可以运行以下命令来查看它正在运行的版本:



openssl version


Enter fullscreen mode Exit fullscreen mode

就我而言,它是LibreSSL版本 2.8.3。

自由主义者

我们可以通过此链接访问其手册文档

手动 openssl

1.生成CA的私钥和证书

我们要使用的第一个命令是openssl req,它代表请求。此命令用于创建和处理证书签名请求。它也可以用于为 CA 创建自签名证书,这正是我们第一步想要的。



openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem


Enter fullscreen mode Exit fullscreen mode

-x509选项用于告诉 openssl 输出自签名证书而不是证书请求。如果您不知道,X509只是公钥证书的标准格式。

-newkey rsa:4096选项的作用是告诉 openssl 同时创建一个新的 RSA 私钥(4096 位)及其证书请求。由于我们同时使用此-x509选项,因此它将输出证书而不是证书请求。

下一个选项是-days 365,它指定证书有效的天数。

然后我们使用-keyout选项告诉 openssl 将创建的私钥写入ca-key.pem文件

最后,-out选择将证书写入ca-cert.pem文件。

当我们运行此命令时,openssl 将开始生成私钥。

生成私钥

一旦生成密钥,我们将被要求提供一个密码,该密码将用于在将私钥写入 PEM 文件之前对其进行加密。

为什么要加密?因为如果私钥文件被黑客入侵,黑客在不知道密码的情况下无法使用它做任何事情。

接下来,openssl会要求我们提供一些身份信息来生成证书:

  • 国家代码
  • 州或省名称
  • 组织名称
  • 单位名称
  • 通用名称(或域名)
  • 电子邮件地址

就这样!证书和私钥文件将成功生成。

生成的密钥和证书

如果我们检查私钥文件ca-key.pem,我们可以看到它显示ENCRYPTED PRIVATE KEY



-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJnzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQILfki090rvloCAggA
MB0GCWCGSAFlAwQBKg...GNYc7i9SVDBoA==
-----END ENCRYPTED PRIVATE KEY-----


Enter fullscreen mode Exit fullscreen mode

ca-cert.pem另一方面,证书未加密,而仅经过 base64 编码,因为它仅包含公钥、身份信息和每个人都可以看到的签名。



-----BEGIN CERTIFICATE-----
MIIFxjCCA64CCQCNT+eP2vjJxzANBgkqhkiG9w0BAQsFADCBpDELMAkGA1UEBhMC
RlIxEjAQBgNVBAgMC...udJwE7HnnA7lpA
-----END CERTIFICATE-----


Enter fullscreen mode Exit fullscreen mode

我们可以使用openssl x509命令显示此证书中编码的所有信息。此命令也可用于签署证书请求,我们稍后会看到。



openssl x509 -in ca-cert.pem -noout -text


Enter fullscreen mode Exit fullscreen mode

这里我们使用-in选项传入 CA 的证书文件。并使用-noout选项告诉它不要输出原始的 base64 编码值。我们之所以使用-text选项,是因为我们想以可读的文本格式显示它。

查看证书

现在我们可以看到证书的所有信息,例如版本号、序列号。由于这是一个自签名证书,因此颁发者和主体是相同的。然后是 RSA 公钥和签名。

我要复制此命令并将其保存到gen.sh脚本中。我希望通过此脚本自动执行生成一组密钥和证书的过程。

文件 gen.sh

在进入第二步之前,我将向您展示另一种提供身份信息的方法,而无需像以前那样以交互方式输入。为此,我们必须在命令-subj中添加 (subject) 选项openssl req



openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/emailAddress=techschool.guru@gmail.com"


Enter fullscreen mode Exit fullscreen mode

在此主题字符串中:

  • /C=FR代表国家
  • /ST=Occitanie适用于州或省
  • /L=Toulouse代表地名或城市
  • /O=Tech School适用于组织
  • /OU=Education适用于组织单位
  • /CN=*.techschool.guru是通用名称或域名
  • /emailAddress=techschool.guru@gmail.com用于电子邮件地址

现在让我们rm *.pem在脚本顶部添加命令(删除所有 pem 文件)gen.sh,并在终端中运行它。



rm *.pem

# 1. Generate CA's private key and self-signed certificate
openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/emailAddress=techschool.guru@gmail.com"

echo "CA's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

# 2. Generate web server's private key and certificate signing request (CSR)

# 3. Use CA's private key to sign web server's CSR and get back the signed certificate


Enter fullscreen mode Exit fullscreen mode

我们仍然被提示输入密码,但它不再要求身份信息,因为我们已经在主题选项中提供了这些信息。

2. 生成 Web 服务器的私钥和 CSR

现在下一步是为我们的 Web 服务器生成私钥和 CSR。

它与我们在第一步中使用的命令几乎相同。不同之处在于,这次我们不想进行自签名,因此应该删除该-x509选项。-days由于我们不创建证书,而只是创建 CSR,因此该选项也应该删除。



openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/emailAddress=pcbook@gmail.com"


Enter fullscreen mode Exit fullscreen mode

输出密钥的名称应为server-key.pem。输出证书请求文件应为server-req.pem。主题应包含我们的 Web 服务器信息。

现在,当我们运行此命令时,将生成加密的私钥和证书签名请求文件。

生成服务器密钥和证书

这次,server-req.pem文件中显示的是CERTIFICATE REQUEST,而不是文件CERTIFICATE中的ca-cert.pem。这是因为它不是像之前那样的证书,而是证书签名请求。



-----BEGIN CERTIFICATE REQUEST-----
MIIE2DCCAsACAQAwgZIxCzAJBgNVBAYTAkZSMRYwFAYDVQQIDA1JbGUgZGUgRnJh
bmNlMQ4wDAYDVQQHDAVQ...pWofr2eOeBQ4Q=
-----END CERTIFICATE REQUEST-----


Enter fullscreen mode Exit fullscreen mode

现在让我们进入第 3 步并签署此请求。

3. 签署 Web 服务器的证书请求

要签署证书,我们将使用之前显示证书时使用的openssl x509命令。让我们打开终端并运行以下命令:



openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem


Enter fullscreen mode Exit fullscreen mode

在这个命令中,我们使用-req选项告诉 openssl 我们将传入一个证书请求。我们使用-in选项,后跟请求文件的名称:server-req.pem

接下来我们使用-CA选项传入CA的证书文件:ca-cert.pem。并-CAkey使用选项传入CA的私钥:ca-key.pem

然后,一个重要的选项是-CAcreateserial。基本上,CA 必须确保其签名的每个证书都具有唯一的序列号。因此,使用此选项时,如果不存在下一个序列号,则会生成一个包含该文件的文件。

最后,我们使用-out选项来指定要将输出证书写入的文件。

询问 CA 的密码

现在正如您所见,由于 CA 的私钥已加密,因此 openssl 要求输入密码才能解密,然后才能使用它来签名证书。这是针对 CA 私钥被黑客入侵的应对措施。

好的,现在我们已经获得了 Web 服务器的签名证书。让我们将其以纯文本格式打印出来。

证书序列号

这是它唯一的序列号0xb141e873fd7b8567。我们还可以看到一个ca-cert.srl文件,里面也包含相同的序列号。



B141E873FD7B8567


Enter fullscreen mode Exit fullscreen mode

默认情况下,证书有效期为30天。我们可以通过-days在签名命令中添加选项来更改它。



openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem


Enter fullscreen mode Exit fullscreen mode

现在有效期已更改为60天。

一个证书可以用于多个域名不同的网站。我们可以通过在签署证书请求时指定“主体备用名称”扩展名来实现这一点。

-extfile该命令的选项允许我们指定包含扩展名的文件。我们可以在此页面openssl x509中看到配置文件的格式

我们可以使用多种名称作为替代名称,例如emailDNSIP。我将创建一个server-ext.cnf包含以下内容的新文件:



subjectAltName=DNS:*.pcbook.com,DNS:*.pcbook.org,IP:0.0.0.0


Enter fullscreen mode Exit fullscreen mode

这里我设置DNS了多个域名:*.pcbook.com*.pcbook.org。我还设置了在本地主机上开发时将使用的域名IP0.0.0.0

现在在证书签名命令中,让我们添加-extfile选项并传入扩展配置文件的名称:



openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf


Enter fullscreen mode Exit fullscreen mode

现在,结果证书文件有一个新的扩展部分,其中包含我们选择的所有主题备用名称:



Certificate:
    ...
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=FR, ST=Occitanie, L=Toulouse, O=Tech School, OU=Education, CN=*.techschool.guru/emailAddress=techschool.guru@gmail.com
        Validity
            Not Before: Apr 10 18:17:05 2020 GMT
            Not After : Jun  9 18:17:05 2020 GMT
        Subject: C=FR, ST=Ile de France, L=Paris, O=PC Book, OU=Computer, CN=*.pcbook.com/emailAddress=pcbook@gmail.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:cb:e2:2b:c3:68:...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:*.pcbook.com, DNS:*.pcbook.org, IP Address:0.0.0.0
    Signature Algorithm: sha1WithRSAEncryption
         5e:67:4d:f7:91:89:fc:...



Enter fullscreen mode Exit fullscreen mode

因此看起来我们的自动化脚本已经准备好了,除了我们必须输入大量密码来保护私钥。

如果我们只是想将其用于开发和测试,我们可以告诉 openssl 不要加密私钥,这样它就不会要求我们输入密码。

我们通过-nodesopenssl req命令添加选项来实现这一点,如下所示:



rm *.pem

# 1. Generate CA's private key and self-signed certificate
openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Tech School/OU=Education/CN=*.techschool.guru/emailAddress=techschool.guru@gmail.com"

echo "CA's self-signed certificate"
openssl x509 -in ca-cert.pem -noout -text

# 2. Generate web server's private key and certificate signing request (CSR)
openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=FR/ST=Ile de France/L=Paris/O=PC Book/OU=Computer/CN=*.pcbook.com/emailAddress=pcbook@gmail.com"

# 3. Use CA's private key to sign web server's CSR and get back the signed certificate
openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

echo "Server's signed certificate"
openssl x509 -in server-cert.pem -noout -text


Enter fullscreen mode Exit fullscreen mode

现在,如果我们再次运行gen.sh,它将不再要求输入密码。如果我们查看私钥文件,它将是PRIVATE KEY,而不是ENCRYPTED PRIVATE KEY像以前那样。



-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDL4ivDaIzDM3my
VDzT2Mw5R9bicXS...AxAt2Ldmc4=
-----END PRIVATE KEY-----


Enter fullscreen mode Exit fullscreen mode

4.验证证书

在结束之前,还有最后一件事,我将向您展示如何验证证书是否有效。我们可以使用openssl verify命令来执行此操作:



openssl verify -CAfile ca-cert.pem server-cert.pem


Enter fullscreen mode Exit fullscreen mode

我们只需传入受信任的 CA 证书和我们要验证的证书即可。如果返回结果,OK则表示证书有效。

今天的文章就到这里。希望对你有用。感谢阅读,我们下期再见!


如果您喜欢这篇文章,请订阅我们的 Youtube 频道在 Twitter 上关注我们,以便将来获取更多教程。


如果你想加入我目前在 Voodoo 的优秀团队,请查看我们的职位空缺。你可以远程办公,也可以在巴黎/阿姆斯特丹/伦敦/柏林/巴塞罗那现场办公,但需获得签证担保。

文章来源:https://dev.to/techschoolguru/how-to-create-sign-ssl-tls-certificates-2aai
PREV
如何安全地存储密码?
NEXT
从 SQL 生成 CRUD Golang 代码 | 比较 db/sql、gorm、sqlx、sqlc