【问题标题】:download cert with curl, echo cert value into openssl使用 curl 下载证书,将证书值回显到 openssl
【发布时间】:2019-02-22 23:50:02
【问题描述】:

我正在尝试使用curl 获取中间证书,并在不将其写入文件的情况下处理该证书。

我已经弄清楚如何处理叶子证书并获取分发点,但这就是我遇到的问题。

例如,让我们以 stackoverflow 为例(似乎相关)。 SO的第一个中间证书来自http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt

在交互式 shell 中,我可以执行以下操作将证书的值存储到变量中:

DigiCertIntermediateCert=$(curl http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt)

然后我可以通过执行以下操作来检查证书的值:

echo "$DigiCertIntermediateCert" | openssl x509 -inform DER -outform PEM

这会输出漂亮且友好的 PEM 形式的证书。它看起来像这样:

-----BEGIN CERTIFICATE-----
MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
...
cPUeybQ=
-----END CERTIFICATE-----

(注意:当中间证书更改时,这会更改,如果这不是您看到的值,请不要惊慌)

整洁!似乎这应该工作。让我们将所有这些逻辑放入带有一些基本案例处理的脚本中(例如,如果证书采用不同的形式,那么我们应该将其解释为那种形式),我们应该完成了,对吧?

#! /bin/bash

cert_content=$(curl -s "$1")
echo "$cert_content"

if echo "$cert_content" | openssl x509 -text -noout; then
    echo "Not converting"
    echo "$cert_content"
else
    echo "Converting"
    echo "$cert_content" | openssl x509 -inform DER -outform PEM
fi

当我们输入 url 时会输出什么?

...
[binary contents of a certificate]
...
unable to load certificate
4667577964:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/pem/pem_lib.c:683:Expecting: TRUSTED CERTIFICATE
Converting
unable to load certificate
4421875308:error:0DFFF08E:asn1 encoding routines:CRYPTO_internal:not enough data:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/asn1/a_d2i_fp.c:251:

所以很容易看出证书是 DER 形式(因为“Converting”行),但看起来证书不完整 - 请注意错误:

unable to load certificate
4421875308:error:0DFFF08E:asn1 encoding routines:CRYPTO_internal:not enough data:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.230.1/libressl-2.6/crypto/asn1/a_d2i_fp.c:251:

说没有足够的数据。

为什么脚本和我在 shell 中执行的操作会有所不同?如何通过 openssl 工具提供二进制证书以获取 PEM 形式的证书?

【问题讨论】:

    标签: bash openssl certificate


    【解决方案1】:

    正如问题所暗示的,我在使用 shell 时不够严格。 “交互式”会话使用zsh 完成,脚本在bash 下运行。 zsh 会将EOF 附加到通过其管道传递的变量,而bash(显然)不会。现在我的任务变成了如何将 EOF 附加到 bash 中的变量(显然,这很重要)。

    【讨论】:

    • 变量中没有 EOF 这样的东西;数据的结尾是隐含的,即使您可以在 终端/控制台输入 上用字符表示 EOF。问题是 bash 无法处理变量中的 null bytes(而 zsh 可以),并且 DER 证书包含相当多的 null 字节。真实程序的注意事项(不是echono shell 可以在参数中传递空字节; Unix API 阻止它。安全的方法是首先存储文本友好的 PEM:cert=$(curl -s ... | openssl x509 -inform der)
    • PS:您知道您可以从任何符合标准的 SSL/TLS 服务器获取中间证书,openssl s_client -connect $host:$port [-servername $host if it uses SNI and OpenSSL < 1.1.1] -showcerts 已经在 PEM 中了吗?
    • @dave_thompson_085 感谢您的回复——我的问题不是关于获得叶子证书,而是更多关于获得中间证书。例如,上次我检查时,SO 的中间证书位于 cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt - 我将如何获取该文件,将其读入变量,然后将其传递给脚本的另一部分 开放式问题,但您的第一条评论帮助解决了它。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 2017-07-26
    相关资源
    最近更新 更多