介绍
在这个实验(Lab)中,你将探索公钥基础设施(PKI)的基础知识,这是支撑互联网上大部分安全(包括 HTTPS)的系统。PKI 是一套创建、管理、分发、使用、存储和撤销数字证书以及管理公钥加密所需的角色、策略、硬件、软件和流程。
你将通过动手实践 openssl 命令行工具来执行 PKI 的核心功能。你将扮演自己的证书颁发机构(CA),为 Web 服务器颁发证书,验证证书的信任链,最后撤销该证书。所有操作都将在 ~/project 目录下执行。
在这个实验(Lab)中,你将探索公钥基础设施(PKI)的基础知识,这是支撑互联网上大部分安全(包括 HTTPS)的系统。PKI 是一套创建、管理、分发、使用、存储和撤销数字证书以及管理公钥加密所需的角色、策略、硬件、软件和流程。
你将通过动手实践 openssl 命令行工具来执行 PKI 的核心功能。你将扮演自己的证书颁发机构(CA),为 Web 服务器颁发证书,验证证书的信任链,最后撤销该证书。所有操作都将在 ~/project 目录下执行。
在这一步中,我们将介绍 PKI 的基本概念。此步骤中无需执行任何命令;目标是在我们开始动手实践之前,建立坚实的理论基础。
PKI 是一个旨在增强电子通信安全性的框架。它通过证书颁发机构 (Certificate Authority, CA) 的方式,利用公钥密码学将公钥与相应的用户身份绑定起来。这种绑定是通过注册和颁发过程建立的。
证书颁发机构是一个颁发数字证书的可信实体。CA 充当一个受信任的第三方,同时被证书的主体(所有者)和依赖该证书的各方所信任。CA 的主要作用是对绑定到特定用户的公钥进行数字签名并发布。
数字证书是一个电子文档(通常遵循 X.509 标准),其中包含:
CA 对证书的签名证明了证书中包含的公钥确实属于证书中命名的实体。
信任链(或证书链)是一系列证书的序列,从一个终端实体证书(例如,针对 example.com 的证书)开始,一直到根 CA 证书结束。
当你的浏览器收到服务器的证书时,它会通过检查颁发者的证书来验证签名。它会沿着这条链向上追溯,直到找到一个已存在于其信任存储区中的根 CA。如果链有效且所有签名都通过验证,则认为该服务器是受信任的。
在下一步中,你将创建自己的根 CA。
在这一步中,你将扮演证书颁发机构(CA),并创建其基础组件:一个私钥和一个自签名根证书。所有命令都将在终端中运行,所有文件都将在你当前的目录 ~/project 中创建。
首先,生成 CA 的私钥。这个密钥是 PKI 中最关键的秘密;它用于签署 CA 颁发的所有证书。
openssl genpkey -algorithm RSA -out ca.key
接下来,你将创建一个自签名根证书。根证书是自签名的,因为它代表了信任的最终锚点;没有更高的权威机构可以对其进行签名。
执行以下命令生成证书。我们使用 -subj 参数来非交互式地提供证书的主题信息。
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.pem -subj "/C=US/ST=California/L=MountainView/O=MyLab/CN=MyLabRootCA"
我们来分解一下这个命令:
req: 证书签名请求(CSR)和证书生成工具。-x509: 输出一个自签名证书而不是 CSR。-new: 创建一个新证书。-nodes: “No DES”,意味着私钥不会用密码短语(passphrase)加密。这在我们的实验中是为了简化操作。-key ca.key: 指定用于签名的私钥。-sha256: 使用 SHA-256 散列算法进行签名。-days 365: 将证书的有效期设置为 365 天。-out ca.pem: 指定新证书的输出文件。-subj "/C=.../CN=...": 提供主题详细信息。CN(通用名,Common Name)是主要身份,对于 CA 来说就是它的名称。你现在拥有了一个 CA 私钥 (ca.key) 和一个根证书 (ca.pem)。你可以检查新 CA 证书的内容:
openssl x509 -in ca.pem -text -noout
滚动查看输出,注意 Issuer(颁发者)和 Subject(主体)字段是相同的,这证实了它是自签名的。
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Validity
Not Before: ...
Not After : ...
Subject: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Subject Public Key Info:
...
在这一步中,你将模拟一个服务器所有者请求证书的过程。你将为服务器生成一个私钥和一个证书签名请求(CSR),然后使用你在上一步中创建的 CA 来签署 CSR 并颁发一个有效的证书。
首先,为服务器生成一个私钥。这个密钥必须在服务器本身上保持机密。
openssl genpkey -algorithm RSA -out server.key
接下来,创建一个证书签名请求(CSR)。CSR 是一段编码文本块,包含公钥以及将包含在证书中的其他信息,例如组织名称和域名。CSR 会被发送给 CA 进行签名。
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=California/L=MountainView/O=MyWebServer/CN=example.com"
请注意,对于服务器证书,CN(通用名,Common Name)必须与服务器的域名匹配,在本例中是 example.com。
现在,作为 CA,你将使用你的 CA 私钥 (ca.key) 来签署服务器的 CSR (server.csr)。此操作将创建最终的服务器证书 (server.crt)。
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.crt -days 300 -sha256
我们来回顾一下新的选项:
x509 -req: 这告诉 OpenSSL 处理一个 CSR。-in server.csr: 输入的 CSR 文件。-CA ca.pem: 用作颁发者的 CA 证书。-CAkey ca.key: 用于签名的 CA 私钥。-CAcreateserial: 这会创建并管理一个序列号文件 (ca.srl),这是确保 CA 颁发的每个证书都具有唯一序列号所必需的。-days 300: 服务器证书的有效期。这个时间应该短于 CA 证书的有效期。最后,检查新创建的服务器证书。
openssl x509 -in server.crt -text -noout
在输出中,观察 Issuer(颁发者)和 Subject(主体)字段。Issuer 应该是你的 CA (MyLabRootCA),而 Subject 应该是你的服务器 (example.com)。这确认了证书已由你的 CA 正确颁发。
Certificate:
Data:
Version: 3 (0x2)
Serial Number: ...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, L = MountainView, O = MyLab, CN = MyLabRootCA
Validity
Not Before: ...
Not After : ...
Subject: C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
...
Signature Algorithm: sha256WithRSAEncryption
...
在这一步中,你将学习如何验证证书链。这是客户端(如网页浏览器)为确定服务器证书是否可信而执行的过程。客户端会检查证书是否由它所信任的 CA 签名。
你可以使用 openssl verify 命令来执行此检查。你需要通过提供根证书来告知 OpenSSL 你信任哪些 CA。
运行以下命令,使用你的根证书 ca.pem 来验证 server.crt:
openssl verify -CAfile ca.pem server.crt
输出应该如下所示:
server.crt: OK
这个 OK 状态确认了:
server.crt 证书确实是由与 ca.pem 中公钥对应的私钥签名的。现在,让我们看看如果验证者(verifier)的信任 CA 列表中没有我们的 CA 会发生什么。你可以通过不带 -CAfile 选项运行 verify 命令来模拟这种情况。
openssl verify server.crt
这次,命令将失败并显示类似以下的错误:
C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.crt: verification failed
错误 "unable to get local issuer certificate" 意味着系统无法在其默认信任存储(trust store)中找到颁发者(MyLabRootCA)的证书。这说明了为什么客户端必须拥有根 CA 证书才能建立信任链是至关重要的。
在这一步中,你将学习如何吊销(revoke)一个证书。当证书的私钥泄露,或者证书在自然到期前不再需要时,吊销是一个关键流程。这通过证书吊销列表(CRL,Certificate Revocation List)来管理。
CRL 是由 CA 颁发的一个数字签名列表,其中包含该 CA 吊销的所有证书的序列号。客户端可以下载 CRL 来检查收到的证书是否仍然有效。
为了管理吊销,openssl 需要一个小的配置文件来知道在哪里可以找到 CA 的数据库文件(index.txt 和 serial)。本实验的设置脚本已经创建了必要的目录(my-ca)和文件。现在,创建配置文件。
使用 cat 命令创建 my-ca.conf:
cat << EOF > my-ca.conf
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./my-ca
database = \$dir/index.txt
serial = \$dir/serial
private_key = ca.key
certificate = ca.pem
default_md = sha256
policy = policy_anything
crl_extensions = crl_ext
default_crl_days = 30
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ crl_ext ]
authorityKeyIdentifier=keyid:always
EOF
这个配置文件告诉 OpenSSL 如何作为一个证书颁发机构(CA)进行操作。每个部分的作用如下:
default_ca = CA_default: 指向主要的 CA 配置部分。dir = ./my-ca: CA 的工作目录,用于存放数据库文件。database = $dir/index.txt: 证书数据库(跟踪已颁发/已吊销的证书)。serial = $dir/serial: 序列号文件,用于唯一的证书 ID。private_key = ca.key: 用于签署证书的 CA 私钥。certificate = ca.pem: CA 自身的证书文件。default_md = sha256: 签名的哈希算法(SHA-256)。policy = policy_anything: 证书验证规则。crl_extensions = crl_ext: CRL 格式化选项。default_crl_days = 30: CRL 的有效期(30 天)。countryName = optional: 国家代码。stateOrProvinceName = optional: 州/省。localityName = optional: 城市/地点。organizationName = optional: 组织名称。organizationalUnitName = optional: 部门。commonName = supplied: 域名/服务器名称(必需)。emailAddress = optional: 电子邮件地址。authorityKeyIdentifier=keyid:always: 在 CRL 中包含 CA 标识符,用于验证。这个配置文件是你的 CA 的“操作手册”。它告诉 OpenSSL 在哪里查找密钥、如何存储证书,以及在颁发和吊销证书时应遵循哪些规则。
现在,吊销服务器证书(server.crt)。此命令将查找证书的序列号,并在 index.txt 数据库文件中将其标记为已吊销。
openssl ca -config my-ca.conf -revoke server.crt
你将看到确认吊销的输出。
吊销后,你必须生成并发布一个更新后的 CRL。
openssl ca -config my-ca.conf -gencrl -out my-ca.crl
这会创建文件 my-ca.crl,其中包含已吊销证书的列表。
最后,我们再次尝试验证服务器证书,但这次,我们还将提供 CRL。正确的验证过程必须检查吊销状态。
openssl verify -CAfile ca.pem -CRLfile my-ca.crl -crl_check server.crt
该命令现在会失败并显示明确的消息:
C = US, ST = California, L = MountainView, O = MyWebServer, CN = example.com
error 23 at 0 depth lookup: certificate revoked
error server.crt: verification failed
"certificate revoked"(证书已吊销)错误确认了我们的吊销过程是成功的。客户端在检查 CRL 时,正确识别出 example.com 的证书不再可信。
恭喜你!你已成功完成了关于公钥基础设施(PKI)基础知识的本次实验。你获得了关于保护数字通信所需基本操作的实践经验。
在本实验中,你学习了如何:
openssl verify 命令验证证书的信任链。这些技能是管理安全系统和理解互联网上如何建立信任的基石。