如何创建和签名SSL/TLS证书?

如何创建和签名SSL / TLS证书?

我们将学习如何生成SSL / TLS证书签名请求(CSR)并由证书颁发机构(CA)对其进行签名。就本教程而言,我们不会将CSR提交给真实的CA。相反,我们将同时扮演两个角色:证书颁发机构和证书申请人。我们将使用openssl执行以下操作:

  1. 生成证书颁发机构(CA)的私钥和自签名证书。
  2. 为我们要使用TLS的Web服务器生成私钥及其配对的证书签名请求(CSR)。
  3. 使用CA的私钥对我们的Web服务器的CSR进行签名,并取回已签名的证书。
  4. 验证证书是否有效。

为了做所有这些事情,需要 openssllibressl已安装。

1. 生成CA的私钥和自签名证书

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

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

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

-newkey rsa:4096选项基本上告诉openssl同时创建新的RSA私钥(4096位)及其证书请求。当我们将其与-x509选项一起使用时,它将输出证书而不是证书请求。

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

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

最后-out选项告诉openssl将证书写入ca-cert.pem文件。

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

执行命令后,将要求我们提供一个密码短语,它将用于在将私钥写入PEM文件之前对其进行加密。

为什么要加密?因为如果以某种方式黑客破坏了私钥文件,那么黑客将无法在不知道密码的情况下使用它执行任何操作解密。

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

  • 国家区号,比如中国就是CN,美国就是US
  • 州或省名称
  • 城市名称
  • 机构名称,随便写
  • 单位名称,随便写
  • 通用名称(或域名)
  • 邮箱地址

这样,证书和私钥文件就成功生成了。

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

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJnDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQI1hrj8iiNzhMCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECC2m96JG0fpdBIIJSE668ot/znRT
-----END ENCRYPTED PRIVATE KEY-----

对于ca-cert.pem,该证书不是加密的,仅以base64编码,因为它只包含公钥,身份信息和签名,每个人都应该看到。

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

让我们执行:

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

在这里,我们使用-in选项来传递CA的证书文件。并且-noout选项告诉它不输出原始的base64编码值。相反,我们使用-text选项,因为我们希望以可读的文本格式显示它。

我要复制这些命令并将其保存到gen.sh脚本中。有了这个脚本,就可以自动化生成一组密钥和证书。

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

openssl req -x509 -newkey rsa:4096 -days 365 -keyout ca-key.pem -out ca-cert.pem -subj "/C=CN/ST=GD/L=GZ/O=Ezzz/OU=Education/CN=*.ezzz.com/emailAddress=ezzz@gmail.com"

在此-subj字符串中:

  • /C=CN 用于国家
  • /ST=GD适用于州或省
  • /L=GZ 用于地区名称或城市
  • /O=Ezzz 用于组织
  • /OU=Education 用于组织单位
  • /CN=*.ezzz.com 用于通用名称或域名
  • /emailAddress=ezzz@gmail.com 用于电子邮件地址

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

仍然会提示输入密码,但是它不再要求提供身份信息,因为我们已经在-subj选项中提供了它们。

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

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

几乎与第一步中使用的命令相同。除此之外,这次我们不想对其自签名,因此我们应该删除-x509选项。 -days选项也应删除,因为我们不是创建证书,而是创建CSR。

openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=CN/ST=GD/L=GZ/O=Ezzz/OU=Education/CN=*.ezzz.com/emailAddress=ezzz@gmail.com"

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

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

-----BEGIN CERTIFICATE REQUEST-----
MIIE1jCCAr4CAQAwgZAxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAlHdWFuZ0Rvbmcx
EjAQBgNVBAcMCUd1YW5nWmhvdTEOMAwGA1UECgwFVmluY2kxEjAQBgNVBAsMCUVk
-----END CERTIFICATE REQUEST-----

现在,我们进入第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

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

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

那么1个重要选项是-CAcreateserial。基本上,CA必须确保它签署的每个证书都具有唯一的序列号。因此,使用此选项,将生成一个包含下一个序列号的文件(如果不存在)。

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

现在您可以在此处看到,因为CA的私钥已加密,所以openssl要求提供密码以对其进行解密,然后才能用于对证书进行签名。它是以防CA的私钥被黑的一种对策。

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

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

这是其唯一的序列号,我们还可以看到一个刚生成的ca-cert.srl文件,其中的0D428A1B04465FD7EF6E671AAB0B16BEB9532BB0序列号其实跟上图中的序列号是相同的,只是这里显示不一样。

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

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

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

证书可用于具有不同域名的多个网站。我们可以通过在签署证书申请时指定主题备用名称扩展名来实现。

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

我们可以使用一些东西作为替代名称,例如电子邮件,DNS或IP。我将创建一个新文件server-ext.cnf写入以下内容:

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

在这里,我将DNS设置为多个域名:*.ezzz.com*.ezzz.org。我还将IP设置为0.0.0.0,这将使用于我们在localhost上开发。

现在,在证书签名命令中,添加-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

让我们为我们的Web服务器签名证书以纯文本格式将其打印出来。

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

可以看到,证书文件具有了新的扩展名部分,其中包含我们选择的所有主题替代名称:

看起来我们的自动化脚本已经准备就绪,当然还是必须输入很多次密码来保护私钥。

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

为此,我们将-nodes选项添加到openssl req命令中,如下所示:

gen.sh

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=CN/ST=GD/L=DZ/O=Ezzz/OU=Education/CN=*.ezzz.com/emailAddress=ezzz@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=CN/ST=GD/L=DZ/O=Ezzz/OU=Education/CN=*.ezzz.com/emailAddress=ezzz@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

现在,如果我们执行gen.sh,它将不再要求输入密码。如果我们看查看ca-key.pem私钥文件,它显示为私钥,而不是像以前那样显示为加密的私钥。

-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDs1R+kzFl3Te7H
0jsHVHtlSnx5bdcBdZNJKjEehjoy5ZU8b9yvAzTbbpu7Hwbd2N99P0ckK3azU2yO
-----END PRIVATE KEY-----

4. 验证证书是否有效

最后,将向您展示如何验证证书是否有效。 我们可以使用openssl verify命令来做到这一点:

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

我们只要传递受信任的CA的证书和要验证的证书。如果返回OK,则证书有效。

希望对您有用。感谢您的阅读,下一个再见!

posted @ 2020-09-22 15:40    阅读(2186)  评论(0编辑  收藏  举报