OpenSSL错误 - 无法获得本地发行人证书



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

$ 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)

不确定该怎么做。

在这里他们说:

openssl无法找到发行人的本地证书(或在TLS握手期间从Web服务器接收的链中的第一个证书的发行人)可以验证签名(S)。

不确定这是什么意思。

此错误意味着证书路径或链条被打破,您缺少证书文件。

- https://wiki.zimbra.com/wiki/fix_depth_lookup:unable_to_to_get_issuer_certificate

update

更多的帮助:

通常由日志消息表明此问题,说"无法获得本地发行人证书"或"自签名证书"之类的东西。验证证书后,必须由OpenSL"信任"其根CA,这通常意味着必须将CA证书放置在目录或文件中,并配置为读取它的相关程序。OPENSL程序"验证"以类似的方式行为,并发出相似的错误消息:检查验证(1)程序手册页以获取更多信息。

  • 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'

更新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中)

OPENSL verify应用程序以以下方式验证证书:它以目标证书开头建立证书链,并追踪发行人链,搜索首先与目标证书一起提供的任何不信任证书。在未能找到不受信任的发行人证书后,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

产生

[... 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。):

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成功验证了另一个usercert。这种差异的关键是,链中的任何一个受信任的证书都具有适当的信任属性用于验证操作。

看近一点(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/manmaster/man1/man1/x509.html#trustrongettings

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

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

如果不存在基本限制扩展,则证书为 被认为是检查其他扩展的"可能的CA" 根据预期的证书使用。发出警告 在这种情况下,因为证书实际上不应被视为 CA:但是,它可以成为CA,可以解决一些破裂 软件。

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

作为备份计划,您始终可以提供整个链条,也可以使用-addtrust黑客制作中级CAS。

https://letsencrypt.org/真的很容易使用和免费。另外,在本地HTTP端口上运行没有SSL的节点,并将NGINX用作HTTPS代理。

sudo apt-get安装certbot nginx

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/host.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/host.com/privkey.pem;
    access_log /var/log/nginx/host.access.log;
    error_log  /var/log/nginx/host.error.log;
    server_name _;
    gzip on;
    gzip_proxied any;
    gzip_types text/css text/javascript text/xml text/plain application/javascript application/x-javascript application/json;
    location / {
        include             /etc/nginx/proxy_params;
        proxy_pass          http://localhost:8080;
        proxy_read_timeout  90s;
        proxy_redirect      http://localhost:8080 https://www.host.com;
    }
}

相关内容

  • 没有找到相关文章

最新更新