节点js SSL "无法获取本地颁发者证书"

12

我已经获得了一个SSL证书,用于签署客户端请求,以及相关的CA证书。我可以使用openssl进行验证:

$ openssl s_client -CAfile /etc/ssl/foo/ca-combined.pem -servername foo.co.in -connect foo.co.in:443
CONNECTED(00000003)
... snip ...
Verify return code: 0 (ok)
---
closed

我将两个 CA 证书合并成一个文件。(I mashed the 2 CA certs into one file). 但是当我尝试使用 Node.js 复制它时:

    var tls = require('tls');
    var fs = require('fs');

    var options = { 
        host: 'foo.co.in',
        servername: 'foo.co.in',
        port: 443,
        key: fs.readFileSync('/etc/ssl/private/foo.key'),
        cert: fs.readFileSync('/etc/ssl/foo/cert.pem'),
        ca: [fs.readFileSync('/etc/ssl/foo/combined-ca.pem')]
    };  

    tls.connect(options, function(err) {
        done(err);
    });

我收到一个错误:
Uncaught Error: unable to get local issuer certificate
  at Error (native)
  at TLSSocket.<anonymous> (_tls_wrap.js:1092:38)
  at TLSSocket._finishInit (_tls_wrap.js:610:8)
  at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38)

我在这里找到了一个答案,建议我需要将每个CA证书放在单独的文件中:
ca: [fs.readFileSync('/etc/ssl/foo/ca.pem'), fs.readFileSync('/etc/ssl/foo/root-ca.pem')]

但是仍然出现了相同的错误。(我还尝试过颠倒顺序)。然后我尝试将中间证书与客户端证书一起放入,并只提供根CA证书作为ca(这似乎是文档建议的),但仍然出现了相同的错误。现在我已经没有更多的想法了。openssl可以正常工作,这表明我做错了什么,有什么建议吗?

$ node --version
v6.10.1

我知道我可以将rejectUnauthorized设置为false,但我真的不想这样做。


你使用哪个后端服务器?nginx、apache还是其他什么? - Ankit Gomkale
这超出了我的控制范围。我给了他们一个CSR,他们为我生成了客户端证书,并给了我CA证书。 - grahamrhay
请参考这个链接:https://dev59.com/e6bja4cB1Zd3GeqPd0r4#46968984 - nilakantha singh deo
关闭验证并不是一个好的解决方案,总的来说。 - grahamrhay
4个回答

5
原来我不需要提供CA证书,因为他们的CA已经被“已知”的机构正确签名。所以我可以从我的请求中删除ca字段。

谢谢!我也遇到了同样的问题,你帮我省了很多时间 :) - Daniel Gruszczyk

4

我创建了一个根证书和一个由根证书签名的中间证书,然后我创建了一个由中间证书签名的服务器和客户端证书。为了测试它,我使用nodejs实现了一个服务器和客户端https,并使用证书进行设置,但是我的客户端出现了以下错误:

problem with request: unable to get local issuer certificate

为了解决这个问题,我需要在我的Node.js代码中,在ca字段中放置我的根证书和中间证书。就像这样:
key: fs.readFileSync('path/client.privkey.pem'),
cert: fs.readFileSync('path/client.cert.pem'),
ca: [ fs.readFileSync('path/intermed-ca.cert.pem'), fs.readFileSync('path/root-ca.cert.pem') ],

对我来说它有效。


1
我该如何创建客户端证书? - devnext

3

针对您的系统,解决此问题有两种不同的选项:

第一种是导出变量NODE_EXTRA_CA_CERTS=$PATH_TO_YOUR_CUSTOM_CA_FILE.pem,指向您的自定义CA_FILE。

第二种是使用选项--use-openssl-ca运行node,如下所示:

node --use-openssl-ca main.js

这假设您已经使用类似以下方式配置了SSL证书:

wget -qP /usr/local/share/ca-certificates http://your_local_cert/local_ca.pem\
    && update-ca-certificates

请查看https://github.com/microsoft/vscode-remote-release/issues/5620


0

当我需要使用自定义SSL证书并将其传递到https.Agentca字段中时,我遇到了相同的问题。

文档清楚地说明,如果您覆盖此字段,则会失去默认情况下存在的所有证书:

使用此选项显式指定CA时,Mozilla的CA将被完全替换。

因此,在我的情况下,为了解决这个问题,我必须在ca数组中添加默认根证书,如下所示:

import https from "https";
import tls from "tls";
import { getMyCustomCert } from "@some-namespace/internal-cert";

new https.Agent({
    ca: [...tls.rootCertificates, getInternalCert()],
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接