【问题标题】:Verification of a certificate chain fails on the leaf certificate叶证书上的证书链验证失败
【发布时间】:2020-07-30 16:39:51
【问题描述】:

我使用pyopenssl 生成了一个 PEM 证书链(CA、中间和叶),并且我想确认我正确定义了所有内容。

这是我采取的步骤:

  1. 我制作了三个 PEM 证书,自签名 CA 并在 this question 之后定义了基本约束 crypto.X509Extension(b'basicConstraints', False, b'CA:TRUE')
  2. 我将 CA 和中间证书复制到 /usr/local/share/ca-certificates(作为 crt 文件)并运行 sudo update-ca-cert
  3. 我已经建立了一个基于this OpenSSL example的简单服务器
  4. 我尝试使用 CA 证书运行服务器并执行 openssl s_client -connect localhost:4433 -CApath /etc/ssl/certs - 效果很好,得到了 Verify return code: 0 (ok)
  5. 做了同样的事情,但这次服务器使用了中间证书 - 也很棒,Verify return code: 0 (ok)
  6. 做了同样的事情,但这次服务器使用叶子证书 - 这次我得到了Verify return code: 24 (invalid CA certificate)

此外,我尝试验证证书并获得以下信息:

$ openssl verify 1-ca.pem
1-ca.pem: OK
$ openssl verify 2-intermediate.pem
2-intermediate.pem: OK
$ openssl verify 3-leaf.pem
C = NL, ST = Amsterdam, L = Zaandam, O = FakeDigiCert, OU = FakeFake, CN = www.fakedigicert.nl
error 24 at 1 depth lookup: invalid CA certificate
error 3-leaf.pem: verification failed

为什么服务器证书离CA超过一步后CA证书突然失效?

【问题讨论】:

  • 您并没有明确说明您在哪个证书中放入了什么,但您说“CA 和中间”,就好像中间不是 CA,它是。你所拥有的是一个根 CA、一个中间 CA 和一个终端实体,也就是叶。 OpenSSL 要求/每个中间 CA 具有 BasicConstraints.ca=true 否则您会收到验证错误 24;至少到目前为止它不需要根 CA,除非代码设置了“严格”​​标志,但根 应该仍然拥有它。
  • @dave_thompson_085 这确实是问题所在。我假设中间证书不一定是 CA。一旦我添加了基本约束,验证就通过了。谢谢!

标签: ssl openssl ssl-certificate pyopenssl


【解决方案1】:

这似乎是大多数人在设置 https 网络服务器时经常遇到的常见陷阱。您还需要向 Web 服务器提供所有中间证书(通常通过将叶子和中间 pem 文件合并到一个 pem 文件中)。因此,当 Web 浏览器访问您的站点时,SSL 设置应该从 Web 服务器返回叶证书和中间证书。

当您将 -showcerts 选项与 opensll s_client 命令一起使用时,您可以在所有提供中间证书的网站上看到这一点:

openssl s_client -connect www.example.com:443 -showcerts

openssl verify 命令也是如此。

来自文档:

-不受信任的文件

用于从主题构建证书链的附加不受信任证书(中间颁发者 CA)的文件 证书到信任锚。该文件应包含一个或多个 PEM 格式的证书。此选项可以指定多个 一次包含来自多个文件的不受信任的证书。

所以在你上面的例子中你需要做:

openssl verify 3-leaf.pem -untrusted 2-intermediate.pem

【讨论】:

  • 省略中间确实是一个常见的错误,但它不能导致这个Q中显示的具体错误。
  • @dave_thompson_085 这是否意味着叶证书在不应该设置时使用“CA:TRUE”?
  • @ShanePowell dave_thompson_085 的解决方案似乎解决了这个问题,但我希望能澄清你所说的。如果我在客户端主机上安装根证书,然后提供包含所有三个证书的链接文件,s_client 的检查应该没问题吗?因为我卸载中间证书时,得到“验证返回码:21(无法验证第一个证书)”
  • @GabeL:按照标准,SSL/TLS 服务器应该发送整个链,除了它可以省略(重要的)根;在您的情况下,它应该至少发送叶子和 imed。大多数服务器(仅)发送您配置的内容,但有些会有所不同。如果服务器错误地只发送了叶子,那么客户端做什么是没有标准的; openssl s_client 特别是,如果您在其信任库中同时拥有 root 和 imed(-CAfile 和/或 -CApath 或它们的默认值),则使用信任库中的 imed 来构建链,并且验证将成功(如果/一旦证书是正确的)。
  • 谢恩:没有。正如我在 Q 上评论的那样,导致验证 24 的原因是 缺少 ca=true 的 intermediate。 OpenSSL 接受 ca=true 的“叶子”——包括但不限于叶子也是根且必须直接受信任的自签名证书。
猜你喜欢
  • 2021-05-20
  • 2021-12-06
  • 2012-03-15
  • 2019-07-03
  • 2022-01-15
  • 2018-03-15
  • 2015-11-13
  • 2021-11-26
  • 2018-09-10
相关资源
最近更新 更多