【问题标题】:Get chain or CA issuer from x509 certificate using OpenSSL CLI使用 OpenSSL CLI 从 x509 证书获取链或 CA 颁发者
【发布时间】:2020-02-04 22:37:00
【问题描述】:

我正在尝试使用 OpenSSL 从证书构建一个链(或只是从某个地方获取它),最好使用命令行界面。

我在互联网上找到了一些示例,但我被困在“我在哪里可以从证书中获得 CA 颁发者?”的问题上

例如查看这个网站openssl command cheatsheet,你会发现命令

openssl s_client -showcerts -host example.com -port 443

获取链子。您可以尝试使用www.google.com 而不是example.com。 输出应该给你链。其他网站迟早会使用相同的命令...

所以,我不能直接从证书中获取链,但我应该在某个地方询问链。

现在我的问题是:我从哪里获得主机名,我可以在哪里发送我对链的请求?

我查看了两个证书。

  1. stackexchange.com
  2. google.com

使用OpenSSL,我可以使用命令询问Issuer

openssl x509 -in certFile -noout -issuer

我分别得到

  1. issuer=C = US,O = Let's Encrypt,CN = Let's Encrypt Authority X3
  2. issuer=C = 美国,O = Google 信任服务,CN = GTS CA 1O1

老实说,我不知道如何处理这些结果......

然后,用命令调查

openssl x509 -text -in certFile

我找到了 AIA 扩展:

  1. CA 颁发者 - URI:http://cert.int-x3.letsencrypt.org/
  2. CA 颁发者 - URI:http://pki.goog/gsr2/GTS1O1.crt

在第一个例子中,我终于可以使用命令了

openssl s_client -showcerts -host http://cert.int-x3.letsencrypt.org/ -port 443

但是使用 google,我不知道如何使用 openssl 下载链...我可以使用 wget,但我没有从 stackexchange 获得的相同格式...

所以,最后,我的问题:

  • 我应该如何处理这些差异?
  • 有没有更好的方法从证书中获取链,而无需询问 CA 颁发者?
  • CA Issuer 是 AIA 的扩展,我认为它不是强制性的,我可以依赖它吗?
  • 如何使用OpenSSL 获取 CA 颁发者,而无需自己解析输出? (类似于openssl x509 -caIssuer -in certFile

PS:我最终尝试实现的是验证证书,遍历整个链,并检查链中每个证书的所有 OCSP 或 CRL...如果您有 C++ 中的工作示例,或者只是使用 OpenSSL CLI,我将不胜感激 :)

编辑:

我现在正在做的是自己创建链。

使用 AIA 扩展,我获得 CA 颁发者 URI,下载 CA 颁发者证书(如果需要,转换为 PEM)等等,直到我不再找到 CA 颁发者。那么,很可能是根CA。

之后,我手动收集所有 pem 并创建链。

【问题讨论】:

  • 您可以使用openssl x509 -in cert.pem -noout -issuer 获取证书的本地颁发者。例如:echo '' | openssl s_client -connect google.com:443 2>/dev/null | openssl x509 -noout -issuer.
  • 而且,是的,您对 Authority Information Access 的看法是正确的,它是 x509 扩展,不是强制性的。
  • 嗨皮卡努。感谢您的评论,但问题是:您的示例中的“google.com”主机名是从哪里获得的?并非每个证书在主题中都有主机名,而且我不知道证书来自哪里...
  • 嗨,n3mo,我对此有点困惑,您至少需要一个 CN 证书才能开始。如果是CN,那么您可以获得证书。如果您有证书,则可以从主题或 SAN 名称中获取 CN。要回答,如果您可以在不询问 CA 的情况下获得整个链,取决于服务器呈现的内容,理想情况下,服务器应该将整个链呈现到根 CA,但如果不是,您需要解析最后一个证书并获取它发行者,也许它也是 URL。
  • 嗨 pikaynu,问题是,它们并不总是 SSL 证书。在 SSL 证书中,CN 通常是一个网站,但在我的情况下,CN 可以只是一个名称……或电子邮件……例如,如果是电子邮件,我的 CN 是该人的个人姓名…… .或者像我写的例子,公司的名称或代码......最后,在与我的同事讨论后,我们决定使用 AIA 扩展(即使不是强制性的,它们似乎总是存在)并使用 CA Issuer URI 构建我们自己的链,直到我们到达根 CA(没有 CA Issuer URI)

标签: openssl x509certificate x509 x509certificatevalidator


【解决方案1】:

知道这有点老了,它已经解决了,但我想我应该添加一个我编写的小脚本来从 x509 输出中解析出 CA Issuer:

getcaissuer() {
openssl x509 -noout -text -in $1 | awk '/^[ \t]+CA Issuers[ \t]+-[ \t]+URI:/ { print gensub(/^.*URI:(.*)$/,"\\1","g",$0); }'
}

# usage:  getcaissuer <certificate>

【讨论】:

  • 对于不熟悉awk 的人(比如我):中间块awk '/... CA Issuers...URI:/ 找到相关行,最后一块{ print gensub(...); } 删除该行的开头( 'CA Issuers - URI:' 部分,因为它不是我们想要的部分。)
【解决方案2】:

似乎互联网上的很多例子都考虑到了 SSL 证书。在 SSL 证书中,您只需连接到网站并下载完整的链。我认为服务器应该在 SSL 协议本身中为您提供完整的链。

我是为 SMIME 证书做的,这就是我感到困惑的原因,因为我不能使用他们用于 SSL 证书的相同方法。

在与我的同事交谈并将我所做的事情与互联网上的一些类似程序进行比较之后,似乎 AIA 扩展程序是正确的方法。也许它在 X509 标准中不是强制性的,但它似乎被广泛使用(我从未见过没有 AIA 扩展的 SMIME 证书)。

然后,我手动创建链,使用 AIA 扩展返回,直到找到没有此类扩展的证书。

此时,这应该是根证书,我将尝试使用机器中安装的证书来验证它。

(当然不要忘记通过CRL或OCSP查看吊销状态)

到目前为止,一切都运行良好:)

【讨论】:

    猜你喜欢
    • 2013-07-09
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多