OpenSSL错误-无法获取本地发行者证书 [英] OpenSSL error - unable to get local issuer certificate

查看:1139
本文介绍了OpenSSL错误-无法获取本地发行者证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple chain setup and can successfully verify in this case:

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

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

However I get errors in these cases:

$ 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中得到它:

Finally, I get it in Node.js when I pass the keys to an HTTPS server:

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 }传递它,但仍然是相同的错误.

I tried passing it with { key, cert, ca }, but still same error.

想知道如何进行调试或如何使HTTPS服务器运行.

Wondering how to go about debugging this or what the fix is to get an HTTPS server running.

如果使用pfx文件,则会得到以下信息:

If I use a pfx file I get the following:

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保留在cert文件中,并将ca属性设置为ca-cert.pem,它将给出:

If I leave only the cert.pem in the cert file, and make the ca attribute be the ca-cert.pem, it gives:

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)

不确定该怎么做.

此处,他们说:

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

OpenSSL is unable to find a local certificate for the issuer (or the issuer of the first certificate in the chain received from the web server during the TLS handshake) with which to verify the signature(s).

不确定这是什么意思.

此错误表示证书路径或证书链已损坏,并且您缺少证书文件.

This error means the certificate path or chain is broken and you are missing certificate files.

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

更新

更多帮助:

此问题通常由日志消息指出,例如无法获得本地发行者证书"或自签名证书".验证证书后,OpenSSL必须信任"其根CA,这通常意味着必须将CA证书放置在目录或文件中,并将相关程序配置为读取该证书. OpenSSL程序的验证"行为类似,并发出类似的错误消息:有关更多信息,请参见verify(1)程序手册页.

This problem is usually indicated by log messages saying something like "unable to get local issuer certificate" or "self signed certificate". When a certificate is verified its root CA must be "trusted" by OpenSSL this typically means that the CA certificate must be placed in a directory or file and the relevant program configured to read it. The OpenSSL program 'verify' behaves in a similar way and issues similar error messages: check the verify(1) program manual page for more information.

  • https://www.openssl.org/docs/faq.html#USER6
    • https://www.openssl.org/docs/faq.html#USER6
    • 但是仍然没有太大帮助.

      But still doesn't help very much.

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

      Looks like Node.js is using a 1.0.2l instead of 1.0.2m but doesn't seem like a big deal.

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

      更新2

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

      Weird, I get this when I make a request from 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

      But when I go to the browser, I don't see the "Proceed with caution" page, and can successfully log a request in Node.js. Maybe that helps somewhat. Please help :D

      推荐答案

      (此答案是从X509_verify_certcrypto/x509/x509_vfy.c:204的openssl-1.0.2m中提取的)

      (This answer extracted from X509_verify_cert at crypto/x509/x509_vfy.c:204, in openssl-1.0.2m)

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

      The OpenSSL verify application verifies a certificate in the following way: It builds the certificate chain starting with the target certificate, and tracing the issuer chain, searching any untrusted certificates supplied along with the target cert first. Upon failing to find an untrusted issuer cert, OpenSSL switches to the trusted certificate store and continues building the chain. This process stops when

      1. 在受信任的商店中找不到发行者.
      2. 遇到自签名证书.
      3. 遇到最大验证深度.

      这时,我们有一条链可能会过早终止(如果找不到发行人,或者超出了验证深度).

      At this point we have a chain that may end prematurely (if we failed to find an issuer, or if we exceeded the verify depth).

      然后,OpenSSL扫描链上的每个受信任证书,以查找指定受信任证书用途的SSLv3扩展.如果受信任的证书具有用于验证操作的目的"的正确信任"属性(或具有anyExtendedKeyUsage属性),则该链是受信任的. (绕过信任属性的浪潮,那部分代码很难阅读.)

      OpenSSL then scans over each trusted certificate on the chain looking for SSLv3 extensions that specify the purpose of the trusted certificate. If the trusted certificate has the right "trust" attributes for the "purpose" of the verification operation (or has the anyExtendedKeyUsage attribute) the chain is trusted. (Forgive the hand-wave on trust attributes, that part of the code was difficult to read.)

      所以让我们测试一下.首先,让我们再现一下OP的错误情况:

      So lets test it out. First, let's repro the OP's error cases:

      #
      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
      

      收益

      [... 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
      

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

      Now, lets use the -addtrust option of openssl x509 to make sure we have one of the acceptable trust attributes on the intermediate CA (call this one IntermediateCAWithTrust; we'll use it to sign 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.造成这种差异的关键在于,链中的任何一个受信任证书都具有用于验证操作的适当信任属性.

      Hey look! we just successfully verified AnotherUserCert via the IntermediateCAWithTrust, even though we didn't supply the whole chain. The key to this difference is that any one of the trusted certificates in the chain had an appropriate trust attribute for the verify operation.

      再仔细一点(via openssl x509 -in ca-crt.pem -noout -text),我们的CA证书已经

      Looking a little closer (via openssl x509 -in ca-crt.pem -noout -text), our CA certificate has

              X509v3 Basic Constraints:
                  CA:TRUE
      

      我可以想象OpenSSL将

      视为一般的可以出于任何目的进行验证"扩展.新的IntermediateCAWithTrust没有X509v3 Basic Constraints,但是有

      which I would imagine OpenSSL treats as a general "may verify for any purpose" extension. The new IntermediateCAWithTrust does not have X509v3 Basic Constraints, but instead has

      Trusted Uses:
        Any Extended Key Usage
      No Rejected Uses.
      

      有关-addtrust选项中的更多信息以及可以添加的信任属性的类型,请参见

      For more info in the -addtrust option, and the types of trust attributes that can be added, see https://www.openssl.org/docs/manmaster/man1/x509.html#TRUST_SETTINGS

      该页面底部附近是上述讨论的简要摘要:

      Near the bottom of that page is a concise summary of the preceding discussion:

      basicConstraints扩展CA标志用于确定是否 该证书可以用作CA.如果CA标志为true,则为 一个CA,如果CA标志为false,则它不是CA.所有CA应具有 CA标志设置为true.

      The basicConstraints extension CA flag is used to determine whether the certificate can be used as a CA. If the CA flag is true then it is a CA, if the CA flag is false then it is not a CA. All CAs should have the CA flag set to true.

      如果缺少basicConstraints扩展名,则证书为 被认为是可能的CA"的其他扩展名会被检查 根据证书的预期用途.发出警告 在这种情况下,因为该证书实际上不应被视为 CA:但是可以允许CA来处理某些损坏的CA 软件.

      If the basicConstraints extension is absent then the certificate is considered to be a "possible CA" other extensions are checked according to the intended use of the certificate. A warning is given in this case because the certificate should really not be regarded as a CA: however it is allowed to be a CA to work around some broken software.

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

      So, in short, make sure your intermediate CAs are properly CAs (in their X509v3 Basic Constraints). This seems an excellent tutorial (and it explicitly generates the intermediate CA as a CA): https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

      作为备份计划,您可以始终提供整个链,也可以使用-addtrust hack来制作中间CA.

      As a backup plan, you can always supply the whole chain, or you can make your intermediate CAs with the -addtrust hack.

      这篇关于OpenSSL错误-无法获取本地发行者证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆