使用 OpenSSL CLI 从 x509 证书获取链或 CA 颁发者

问题描述 投票:0回答:3

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

我在互联网上找到了一些例子,但我陷入了“我在哪里从证书中获取 CA 颁发者?”的问题

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

openssl s_client -showcerts -主机 example.com -端口 443

获得链条。您可以尝试使用

www.google.com
而不是
example.com
。 输出应该给你链。其他网站迟早会使用相同的命令......

所以,我无法直接从证书中获取链,但我应该向某个地方询问链。

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

我查看了两张证书。

  1. stackexchange.com
  2. google.com

使用

OpenSSL
,我可以使用命令询问发行人

openssl x509 -in certFile -noout -颁发者

我分别得到

  1. 发行人=C = US,O = Let's Encrypt,CN = Let's Encrypt 授权机构 X3
  2. 发行人=C = US,O = Google Trust Services,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/ -端口 443

但是对于谷歌,我不知道如何使用

openssl
下载链......我也许可以使用
wget
,但我没有从stackexchange获得的相同格式...

最后,我的问题是:

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

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

编辑:

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

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

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

openssl x509certificate x509 x509certificatevalidator
3个回答
3
投票

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

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

# usage:  getcaissuer <certificate>

3
投票

利用@bng44270的答案,这个脚本将沿着链向上抓取证书到当前目录

#!/bin/bash
# get-cert-chain.sh

machine=${1?No address passed}

machine_cert=${machine}.pem

# from https://stackoverflow.com/a/68637388/5401366
getcaissuer() {
    openssl x509 -noout -text -in $1 -ext authorityInfoAccess | awk '/^[ \t]+CA Issuers[ \t]+-[ \t]+URI:/ { print gensub(/^.*URI:(.*)$/,"\\1","g",$0); }'
}

if [ ! -e "${machine_cert}" ];
then
    openssl s_client -connect ${machine}:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM >${machine_cert}
fi;

cur_cert=$machine_cert

while :;
do
    # Get the first matching http line to grab the next cert loc
    nextca=$(getcaissuer ${cur_cert} | grep -m1 http)

    # ran out of stuff to retrieve
    [ -z "${nextca}" ] && break

    echo "Trying to get '${nextca}'"

    nextfile=$(basename ${nextca})

    if [ ! -e ${nextfile} ];
    then
        echo "Getting $nextca"
        curl -sO $nextca
    else
        echo "Found ${nextfile}"
    fi

    # Convert
    openssl x509 -in $nextfile -outform PEM > ${nextfile}.pem

    # down the rabbit hole...
    cur_cert=${nextfile}.pem

done

-1
投票

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

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

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

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

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

(当然,别忘了通过CRL或OCSP检查吊销状态)

到目前为止,一切都很顺利:)

© www.soinside.com 2019 - 2024. All rights reserved.