如何正确创建和使用交叉签名的 CA 和证书

信息安全 公钥基础设施 openssl x.509
2021-09-06 18:08:36

我正在尝试使用交叉签名的 CA 创建一个环境,并验证针对其中一个 CA 颁发的证书,所有这些都使用openssl. 到目前为止,我得到的最好的结果是openssl在验证时进入无限循环(循环在 100 级终止)。

我已经发布了我创建的所有证书现在,我正在做出许多假设,并且主要基于此 Oasis 文档来构建模型。以下是我的假设:

  1. 应该有 4 个证书,由权威 #1 和 #2 自签名和交叉签名,其中权威 #1 由权威 #2 签名,反之亦然。
  2. 仅使用了 2 个实际主题 (DN)(授权机构用于自签名的同一主题是其他授权机构签署的主题,尽管证书不同)。
  3. 所有 4 个证书都应该是最终用户信任的一部分。
  4. 对于自签名证书和交叉签名证书,同一机构使用的密钥应该相同
  5. 不应该使用 AKI(可能是“不应该”这个词太强了,但不使用它不应该有伤害。因为相同的键规则,但这不重要)
  6. 我尝试为交叉签名证书设置 CA:TRUE,结果相同。

我对交叉签名的理解是,它为验证过程提供了替代路径。考虑到我看到openssl循环,似乎每次都在选择交叉签名证书。所以问题的关键是 - 考虑到两者具有相同的主题,什么会使验证过程有利于自签名证书而不是交叉签名证书。

这是一个测试叶证书,我无法openssl verify成功验证它。

[vps@druid]~/ws/EF/pki3$  openssl verify -verbose -CAfile cas.pem cert.pem 
cert.pem: C = US, O = Excelfore, OU = PoC, CN = xl4 CA 2
error 2 at 100 depth lookup:unable to get issuer certificate
2个回答

好的,这是迄今为止我想出的最好的。

我相信深度处理的问题只是 OpenSSL 的问题。不能建立正确的路径是不好的。RFC-5280,第 6.1 节说:

证书不得在预期的认证路径中出现多次。

OpenSSL 可能违反了这一点。但是,我不得不说,除了Sec 3.2之外,我在RFC-5280中并没有看到关于如何构建路径的解释有人建议路径必须在每条链的末尾以单个自签名 CA 结尾(但是,这与验证链不应该有信任锚,但信任锚可能包含中间证书的声明相矛盾,这使得 post-链端包含多个证书,其中 OpenSSL 以无限循环结束)。无论哪种方式,我都不同意 OpenSSL 的做法。

我还应该说,我所说的不仅仅是交叉签名证书,而是相互交叉签名的证书。明显的区别是,普通的交叉签名不会创建这样的循环依赖,而是通过一个 CA 的信任锚来实现的,该信任锚由另一个 CA 签名(从验证者的角度来看,这与可信中介的情况相同) , AFAIU)。

使其与 OpenSSL 一起工作的方法是不将交叉签名证书添加到信任列表中,而是将它们作为密钥持有者生成的中间证书的一部分提供。

如果我将所有自签名trust.pem、所有交叉证书放入untrust.pem,则验证程序可以工作,尽管会产生中间错误(这很有意义,因为并非所有树都成功构建/验证):

这是两个根都存在的情况:

$  openssl verify -verbose -CAfile trust.pem -untrusted nontrust.pem host1/cert.pem 
host1/cert.pem: C = US, O = Excelfore, OU = PoC, CN = xl4 CA 1
error 24 at 1 depth lookup:invalid CA certificate
C = US, O = Excelfore, OU = PoC, CN = xl4 CA 2
error 24 at 2 depth lookup:invalid CA certificate
OK

这里只存在一个或另一个根:

$  openssl verify -verbose -CAfile ca1/ca1.pem -untrusted nontrust.pem host1/cert.pem 
host1/cert.pem: C = US, O = Excelfore, OU = PoC, CN = xl4 CA 1
error 24 at 1 depth lookup:invalid CA certificate
C = US, O = Excelfore, OU = PoC, CN = xl4 CA 2
error 24 at 2 depth lookup:invalid CA certificate
OK
$  openssl verify -verbose -CAfile ca2/ca2.pem -untrusted nontrust.pem host1/cert.pem 
host1/cert.pem: C = US, O = Excelfore, OU = PoC, CN = xl4 CA 1
error 24 at 1 depth lookup:invalid CA certificate
OK

这显示了交叉签名中最酷的部分,我们可以核对 CA,并且仍然可以使用原始证书。

然而

RFC-5246,秒。记录 TLS 1.2 的7.4.2说服务器只有一个链可以呈现给客户端(反之亦然)。如果交叉签名证书不能成为信任库的一部分,那么客户端必须提供多个链,以便验证方有选项。所以,是的,它在理论上有效,但不适用于 SSL(它可能适用于其他验证协议,我没有检查),至少在它的 OpenSSL 实现中。

首先让我说,我的回答中包含了一些猜测。我最好的猜测是您颁发了 2 个叶子证书,并且一个证书的颁发者指向另一个证书颁发者,反之亦然,从而导致了循环。

我没有尝试自己重现您的问题,但确实使用了交叉签名。LE 站点(LE交叉签名)和您的提示使我成功地发行和使用了交叉签名证书。我的目标不是 CA 根恢复,而是 CA 根翻转。如果您的角色是 CA,那么它基本上与您尝试实现的目标没有太大区别。关键因素是:

  • 主题字段必须相同(参见上文)
  • 密钥必须相同(参见上文)
  • 证书必须有不同的颁发者,并且 1 可以自签名,就像我的应用程序一样

部分类似于 LE 链接,我创建了一个交叉签名的中间证书和一个新的根证书。永久中间证书 (PATHLEN:0) 由 2 个交叉签名证书之一签名,哪个不重要,因为主题和密钥是相同的。提示:为两者重用未来交叉证书的 CSR,所以 Subject 不会错。在交叉签名(临时)中间证书上,我将 PATHLEN 设置为 1(不能为 0!)

说得很清楚:

  • 路径 1(旧根):叶子证书,烫发。中级证书,临时。中级证书,“旧”根证书
  • 路径 2(新根):叶子证书,烫发。中级证书,“新”根证书

您可以随意使用 SAN 和开始/结束日期。“旧”根路径中的中间证书(临时或翻转)有效期为 5 年,“新”根路径为 10 年。导入“新”根证书后,Firefox 立即使用较短的 (4 → 3) 路径。在我的情况下,您需要在网络服务器上加载 3 个证书:叶子证书、烫发。中级证书,临时。中间(“旧”根/临时/翻转)证书。

OpenSSL 并没有让我失望地测试叶子证书的有效路径。我将 OpenSSL 的验证工具与 CAfile 一起用于路径中的根目录,并且对使用的中间证书不信任。可以通过这种方式验证到旧根和新根的路径。

作为最终用户(非 CA),如果您想要有弹性,它应该与 1 个 CSR 一起从 2 个 CA 获取(订购)叶子证书,并使用与中间证书链接的这 2 个证书加载您的 Web 服务器颁发 CA。所以总共有4个证书。