OpenSSL 错误 - 无法获取本地颁发者证书

2024-03-28

我有一个简单的链设置,在这种情况下可以成功验证:

$ openssl version
OpenSSL 1.0.2m  2 Nov 2017
$ openssl verify -CAfile chain.pem cert.pem
cert.pem: OK

但是我在这些情况下遇到错误:

$ openssl verify -CAfile ca-cert.pem cert.pem
cert.pem: C = US...
error 2 at 1 depth lookup:unable to get issuer certificate

具体来说无法获取颁发者证书.

也可以在这里获取:

$ openssl verify chain.pem
chain.pem: C = US...
error 20 at 0 depth lookup:unable to get local issuer certificate

$ openssl verify cert.pem
cert.pem: C...
error 20 at 0 depth lookup:unable to get local issuer certificate

最后,当我将密钥传递给 HTTPS 服务器时,我在 Node.js 中得到了它:

events.js:193
      throw er; // Unhandled 'error' event
      ^

Error: unable to get local issuer certificate
    at TLSSocket.onConnectSecure (_tls_wrap.js:1036:34)
    at emitNone (events.js:115:13)
    at TLSSocket.emit (events.js:218:7)
    at TLSSocket._finishInit (_tls_wrap.js:637:8)

我尝试通过它{ key, cert, ca },但仍然出现同样的错误。

想知道如何调试这个问题或者修复什么才能让 HTTPS 服务器运行。

如果我使用一个pfx文件我得到以下内容:

events.js:193
      throw er; // Unhandled 'error' event
      ^

Error: self signed certificate in certificate chain
    at TLSSocket.onConnectSecure (_tls_wrap.js:1036:34)
    at emitNone (events.js:115:13)
    at TLSSocket.emit (events.js:218:7)
    at TLSSocket._finishInit (_tls_wrap.js:637:8)

如果我只将 cert.pem 留在证书文件中,然后将ca属性是 ca-cert.pem,它给出:

Error: unable to verify the first certificate
    at TLSSocket.<anonymous> (_tls_wrap.js:1108:38)
    at emitNone (events.js:105:13)
    at TLSSocket.emit (events.js:207:7)
    at TLSSocket._finishInit (_tls_wrap.js:638:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:468:38)

不知道该怎么办。

Here https://stackoverflow.com/questions/31619825/unable-to-openssl-verify-ssl-certificate他们说:

OpenSSL 无法找到颁发者(或在 TLS 握手期间从 Web 服务器收到的链中第一个证书的颁发者)的本地证书来验证签名。

不确定那是什么意思。

此错误意味着证书路径或链已损坏,并且您丢失了证书文件。

- https://wiki.zimbra.com/wiki/Fix_depth_lookup:unable_to_get_issuer_certificate https://wiki.zimbra.com/wiki/Fix_depth_lookup:unable_to_get_issuer_certificate

Update

更多帮助:

此问题通常由日志消息表明,例如“无法获取本地颁发者证书”或“自签名证书”。当验证证书时,其根 CA 必须受到 OpenSSL“信任”,这通常意味着 CA 证书必须放置在目录或文件中,并且相关程序配置为读取它。 OpenSSL 程序“verify”的行为方式类似,并发出类似的错误消息:请检查 verify(1) 程序手册页以获取更多信息。

  • https://www.openssl.org/docs/faq.html#USER6 https://www.openssl.org/docs/faq.html#USER6

但仍然没有多大帮助。

看起来 Node.js 使用的是 1.0.2l 而不是 1.0.2m,但似乎没什么大不了的。

$ node -pe process.versions | grep openssl
  openssl: '1.0.2l'

Update 2

奇怪的是,当我从 Node.js 发出请求时,我得到了这个:

Uncaught Error: unable to verify the first certificate
      at TLSSocket.onConnectSecure (_tls_wrap.js:1036:34)
      at TLSSocket._finishInit (_tls_wrap.js:637:8)

但是当我进入浏览器时,我没有看到“谨慎继续”页面,并且可以在 Node.js 中成功记录请求。也许这会有所帮助。请帮忙:D


(此答案摘自X509_verify_cert at crypto/x509/x509_vfy.c:204,在 openssl-1.0.2m 中)

OpenSSLverify应用程序按以下方式验证证书:它从目标证书开始构建证书链,并跟踪颁发者链,首先搜索与目标证书一起提供的任何不受信任的证书。在找不到不受信任的颁发者证书时,OpenSSL 会切换到受信任的证书存储并继续构建链。该过程停止时

  1. 在可信存储中找不到发行者。
  2. 遇到自签名证书。
  3. 遇到最大验证深度。

此时,我们的链可能会提前结束(如果我们未能找到发行者,或者如果我们超出了验证深度)。

然后,OpenSSL 扫描链上的每个受信任证书,查找指定受信任证书用途的 SSLv3 扩展。如果可信证书具有用于验证操作“目的”的正确“信任”属性(或者具有anyExtendedKeyUsage属性)该链是可信的。 (请原谅对信任属性的挥手,这部分代码很难阅读。)

那么我们来测试一下。首先,让我们重现OP的错误案例:

#
echo "Making Root CA..."
openssl req -newkey rsa:4096 -nodes -keyout ca-key.pem -sha384 -x509 -days 365 -out ca-crt.pem -subj /C=XX/ST=YY/O=RootCA

echo "Making Intermediate CA..."
openssl req -newkey rsa:3072 -nodes -keyout int-key.pem -new -sha384 -out int-csr.pem -subj /C=XX/ST=YY/O=IntermediateCA
openssl x509 -req -days 360 -in int-csr.pem -CA ca-crt.pem -CAkey ca-key.pem -CAcreateserial -out int-crt.pem

echo "Making User Cert..."
openssl req -newkey rsa:2048 -nodes -keyout usr-key.pem -new -sha256 -out usr-csr.pem -subj /C=XX/ST=YY/O=LockCmpXchg8b
openssl x509 -req -days 360 -in usr-csr.pem -CA int-crt.pem -CAkey int-key.pem -CAcreateserial -out usr-crt.pem

echo ""
echo "Making Chain..."
cat ca-crt.pem int-crt.pem > chain.pem

echo ""
echo "Verfying UserCert via RootCA..."
openssl verify -CAfile ca-crt.pem usr-crt.pem

echo ""
echo "Verfying UserCert via IntermediateCA..."
openssl verify -CAfile int-crt.pem usr-crt.pem

echo ""
echo "Verfying UserCert via chain..."
openssl verify -CAfile chain.pem usr-crt.pem

yields

[... Skipping OpenSSL KeyGen / CertGen verbosity ...]
Making Chain...

Verfying UserCert via RootCA...
usr-crt.pem: C = XX, ST = YY, O = LockCmpXchg8b
error 20 at 0 depth lookup:unable to get local issuer certificate

Verfying UserCert via IntermediateCA...
usr-crt.pem: C = XX, ST = YY, O = IntermediateCA
error 2 at 1 depth lookup:unable to get issuer certificate

Verfying UserCert via chain...
usr-crt.pem: OK

现在,让我们使用-addtrust的选项openssl x509确保我们在中间 CA 上拥有可接受的信任属性之一(将此称为IntermediateCAWithTrust;我们将用它来签名AnotherUserCert.):

echo ""
echo "Alternate Intermedate CA (using -addtrust anyExtendedKeyUsage)"
echo ""

echo "Making IntermediateCAWithTrust..."
openssl req -newkey rsa:3072 -nodes -keyout int-key2.pem -new -sha384 -out int-csr2.pem -subj /C=XX/ST=YY/O=IntermediateCAWithTrust
openssl x509 -req -days 360 -in int-csr2.pem -CA ca-crt.pem -CAkey ca-key.pem -CAcreateserial -out int-crt2.pem -addtrust anyExtendedKeyUsage

echo "Making AnotherUser Cert..."
openssl req -newkey rsa:2048 -nodes -keyout usr-key2.pem -new -sha256 -out usr-csr2.pem -subj /C=XX/ST=YY/O=LockCmpXchg8b_2
openssl x509 -req -days 360 -in usr-csr2.pem -CA int-crt2.pem -CAkey int-key2.pem -CAcreateserial -out usr-crt2.pem

echo ""
echo "Verfying AnotherUserCert via IntermediateCAWithTrust..."
openssl verify -CAfile int-crt2.pem usr-crt2.pem

这产生

Alternate Intermedate CA (using -addtrust anyExtendedKeyUsage)

Making IntermediateCAWithTrust...
[... Snip more OpenSSL generation output ...]
Making AnotherUser Cert...
[... Snip more OpenSSL generation output ...]

Verfying AnotherUserCert via IntermediateCAWithTrust...
usr-crt2.pem: OK

你看!我们刚刚通过 IntermediateCAWithTrust 成功验证了 AnotherUserCert,即使我们没有提供整个链。这种差异的关键在于链中的任何一个受信任的证书都具有适当的信任属性用于验证操作。

靠近一点看(via openssl x509 -in ca-crt.pem -noout -text),我们的CA证书有

        X509v3 Basic Constraints:
            CA:TRUE

我认为 OpenSSL 将其视为一般的“可以出于任何目的进行验证”扩展。新的IntermediateCAWithTrust不具有X509v3 Basic Constraints,而是有

Trusted Uses:
  Any Extended Key Usage
No Rejected Uses.

欲了解更多信息,请参阅-addtrust选项以及可以添加的信任属性类型,请参见https://www.openssl.org/docs/manmaster/man1/x509.html#TRUST_SETTINGS https://www.openssl.org/docs/manmaster/man1/x509.html#TRUST_SETTINGS

该页面底部附近是前面讨论的简明摘要:

basicConstraints 扩展 CA 标志用于确定是否 该证书可以用作 CA。如果 CA 标志为真,那么它是 CA,如果 CA 标志为 false,则它不是 CA。所有 CA 都应该有 CA 标志设置为 true。

如果 basicConstraints 扩展不存在,则证书为 被认为是“可能的 CA”,检查其他扩展名 根据证书的预期用途。发出警告 在这种情况下,因为证书实际上不应该被视为 CA:但是允许使用 CA 来解决一些损坏的问题 软件。

因此,简而言之,请确保您的中间 CA 是正确的 CA(在其X509v3 Basic Constraints)。这似乎是一个很棒的教程(它显式生成中间 CA 作为 CA):https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

作为备份计划,您始终可以提供整个链,或者您可以使用-addtrust hack.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenSSL 错误 - 无法获取本地颁发者证书 的相关文章

随机推荐

  • ASP.net MasterPage.master 不存在

    我在 IIS 服务器上发布我的网站时遇到问题 我无法直接访问它 因此我必须依靠其他人在 IIS 上配置我的网站 但是 当我上传我的网站时 出现此错误 Line 1 Line 2
  • Maven 程序集创建带有依赖项和类路径的 jar

    我有一个 Maven 项目 有很多依赖项 我想使用程序集插件将所有依赖项打包到一个 jar 中 但我不会将所有依赖项 jar 解压得一团糟 我希望它们全部进入 lib 文件夹 但我不知道如何添加类路径 我的pom
  • Orchard CMS - 配置基本 URL

    我使用 localhost frankgiotto 的基本 URL 在我的开发计算机上安装了最新版本的 Orchard 然后我将网站移至 www frankgiotto com 并在设置中更新了我的基本 URL 网站运行完美 我喜欢它的一切
  • 了解 intel 汇编中的 %rip 寄存器

    关于以下小代码 在另一篇关于结构大小和正确对齐数据的可能性的文章中对此进行了说明 struct char Data1 short Data2 int Data3 char Data4 x unsigned fun void x Data1
  • 想要计算列中满足条件的值的数量

    我正在尝试计算列中满足特定条件 例如 大于 0 75 的值的数量 我的列由 2000 多个小数组成 这是我尝试过的 a len fs c np zeros a for i in fs 0 a if i gt 0 75 print 1 eli
  • Django REST Framework Swagger - 身份验证错误

    我按照说明进行操作在文档中 http django rest swagger readthedocs io en latest 所以这是我的观点 from rest framework decorators import api view
  • 在 Android 中获取 WiFi 信号强度

    我可以使用以下代码获取以 dBm 为单位的 WiFi 信号电平 for ScanResult result wifiScanResultList int signalLevel result level 它给出负值 当我们看到默认的系统 W
  • Android 中的微调器出现错误

    我正在使用新样式的 Spinner Base Widget AppCompat Spinner Underlined 当我选择选项时 我可以看到下划线 并且该线以强调色显示 问题是我找不到一种方法来显示带有红色下划线的错误 例如谷歌对其所有
  • 在python中导入外部“.txt”文件

    我正在尝试导入包含大约 10 个单词的列表的文本 import words txt 那不行 无论如何 我可以在不显示此内容的情况下导入文件吗 Traceback most recent call last File D python p1
  • 在 prestashop 管理的编辑产品页面添加一个字段

    我在 prestashop 数据库的产品表中添加了一个字段 mystock 现在我想在编辑产品页面中显示 编辑此字段 产品更新时也会更新 这个适用于我的 prestashop 1 5 4 将文件 Product php 添加到 overri
  • 通过 R 中的因子向量化 cumsum

    我正在尝试在一个非常大的数据帧 约 220 万行 中创建一个列 用于计算每个因子级别的 1 的累积和 并在达到新的因子级别时重置 下面是一些与我自己的类似的基本数据 itemcode lt c a1 a1 a1 a1 a1 a2 a2 a3
  • 查找 boost multi index 标签到索引和索引数量

    我有一个模板类 CrMultiIndex 它接收 boost 多索引 GlobalHash 的定义作为模板参数 I need 根据使用的索引向我的模板类添加统计信息 所以我需要一种方法在初始化时使用现有索引的数量调整向量 m StatsBy
  • iOS10 SDK什么时候设置视图帧大小?

    多年来 我一直在 Swift 和 ObjC 中使用这种技术来制作圆形视图 view layer cornerRadius view frame size width 2 view clipsToBounds true 当 Storyboar
  • 串行版本 UID 有何用途? [复制]

    这个问题在这里已经有答案了 我正在创建一个 Java 应用程序 当创建一个与 ADT 一起使用的接口时 它发现需要将一个随机数初始化为 ID 号 public class StackFullException extends Runtime
  • DomIcon 的集群

    我正在尝试制作集群H map DomMarker 正在使用H map DomIcon与 HTML 代码 但原生的 Here Map 聚类不起作用 仅当我使用简单的H map Icon 但由于这被渲染为canvas图层 我无法使用自己的标记
  • MFC:如何捕获Web浏览器控件中的链接单击事件?

    我有一个带有 Web 控件的 MFC 应用程序 单击可单击链接时 它将使用 IE 打开 而不是默认浏览器 问题 有没有办法强制使用默认浏览器打开它 如果没有 我如何捕获链接单击事件 以便稍后可以操纵单击事件 谢谢 不 据我所知还没有 查看有
  • 在 Mathematica 中导入 Google Sketchup 模型

    Google 的 Sketchup 是一个漂亮 简单的 3D 对象建模器 此外 谷歌还拥有巨大的3D 对象仓库 http sketchup google com 3dwarehouse 因此 如果您在这方面不是特别有天赋 实际上您不必自己做
  • R 包“partykit”在 ctree_control 中未使用参数

    我想使用 partykit 包通过 ctree 和 cforest 构建分类树和森林 由于我的数据集包含 50000 行和 30 列 因此我想将 minsplit 设置为 150 将 minbucket 设置为 50 不幸的是 当我输入我的
  • 与 xgboost 并行线程?

    根据其文档 xgboost 有一个 n jobs 参数 但是 当我尝试设置 n jobs 时 出现此错误 TypeError init got an unexpected keyword argument n jobs 其他一些参数 如 r
  • OpenSSL 错误 - 无法获取本地颁发者证书

    我有一个简单的链设置 在这种情况下可以成功验证 openssl version OpenSSL 1 0 2m 2 Nov 2017 openssl verify CAfile chain pem cert pem cert pem OK 但