无法验证叶签名

我正在使用 node.js request.js 来访问一个 api,我得到了这个错误

[错误: UNABLE _ TO _ VERIFY _ LEAF _ SIGNATURE ]

我所有的证件都是准确有效的,服务器也没问题,我也向邮递员提出了同样的要求。

request({
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});

这段代码只是在可执行脚本 ex 中运行。node ./run_file.js是这个原因吗?它需要在服务器上运行吗?

270587 次浏览

这不是应用程序的问题,而是由中间 CA 签名的证书的问题。 如果您接受这一事实并且仍然希望继续,请在请求选项中添加以下内容:

rejectUnauthorized: false

全部要求:

request({
"rejectUnauthorized": false,
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});

注意 : 以下内容是危险的,将允许在客户端和服务器之间截获和修改 API 内容。

这也起作用了

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

安全解决方案

首先从 npm 安装 Ssl-root-cas包:

npm install ssl-root-cas

此包包含许多浏览器信任但节点不信任的中间证书。

var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()

将添加缺失的证书。更多信息请参见:

Https://git.coolaj86.com/coolaj86/ssl-root-cas.js

CoolAJ86的解决方案是正确的,它不会像使用 rejectUnauthorizedNODE_TLS_REJECT_UNAUTHORIZED禁用所有检查那样危害您的安全性。不过,您可能需要显式地注入另一个 CA 的证书。

我首先尝试了 Ssl-root-cas模块包含的根 CA:

require('ssl-root-cas/latest')
.inject();

结果仍然是 UNABLE_TO_VERIFY_LEAF_SIGNATURE错误。然后我发现是谁为我通过 COMODO SSL 分析仪连接到的网站颁发了证书,下载了该机构的证书,并试图只添加一个:

require('ssl-root-cas/latest')
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

我最终得到了另一个错误: CERT_UNTRUSTED。最后,我注入了额外的根 CA,并包含了“ my”(显然是中间的) CA,它起作用了:

require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

只是把这个放在这里,以防有人需要帮助,我的情况是不同的,有点奇怪的组合。我是在一个通过 超级经纪人访问的请求上得到这个结果的——这个问题与证书(正确设置的证书)没有任何关系,而是与我通过 异步模块的瀑布回调传递超级代理结果这一事实有关。修复: 不传递整个结果,而是通过瀑布的回调传递 result.body

在子域上安装 GoDaddy 证书后,我的 Apache 配置出现了问题。我最初认为 Node 不发送服务器名称指示器(SNI)可能是一个问题,但事实并非如此。使用 https://www.ssllabs.com/ssltest/分析子域的 SSL 证书会返回错误 连锁问题: 不完整

在通过 SSLCertificateChainFile Apache 指令添加 GoDaddy 提供的 gd_bundle-g2-g1.crt文件后,Node 能够通过 HTTPS 连接,错误消失了。

我也有同样的问题。我一直遵循@ThomasReggi 和@CoolAJ86的解决方案,并且工作得很好,但是我对这个解决方案并不满意。

因为“ UNABLE _ TO _ VERIFY _ LEAF _ SIGNATURE”问题是由于认证配置级别而发生的。

我接受@Thirdender 的解决方案,但它的部分解决方案。根据 Nginx官方网站,他们明确提到证书应该是服务器证书和链式证书的组合。

enter image description here

对于 创建应用程序(也会出现这个错误,这个问题是 Google 的第一个结果) ,你可能在开发时使用了 HTTPS=true npm startproxy(在 package.json中) ,它们转到一些 HTTPS API,而这些 API 本身是自签名的。

如果是这样的话,考虑像这样改变 proxy:

"proxy": {
"/api": {
"target": "https://localhost:5001",
"secure": false
}
}

secure决定 WebPack 代理是否检查证书链,并禁用它确保 API 自签名证书不会被验证,以便您获得数据。

您必须在服务器中包含中级证书。这解决了[错误: UNABLE _ TO _ VERIFY _ LEAF _ SIGNATURE ]

这可能是非常诱人的做 rejectUnauthorized: falseprocess.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';,但不要这样做!它让你暴露在中间人的攻击之下。

其他答案是正确的,因为问题在于您的证书是“由中间 CA 签署的”有一个简单的解决方案,它不需要像 ssl-root-cas这样的第三方库,也不需要向节点注入任何额外的 CA。

节点中的大多数 https 客户端支持允许您为每个请求指定 CA 的选项,这将解析 UNABLE_TO_VERIFY_LEAF_SIGNATURE。下面是一个使用节点的内置 https模块的简单示例。

import https from 'https';


const options = {
host: '<your host>',
defaultPort: 443,
path: '<your path>',
// assuming the bundle file is co-located with this file
ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
headers: {
'content-type': 'application/json',
}
};
https.get(options, res => {
// do whatever you need to do
})

但是,如果可以在宿主服务器中配置 ssl 设置,最好的解决方案是将中间证书添加到宿主提供商。这样,客户机请求者就不需要指定 CA,因为它包含在服务器本身中。我个人使用 namecheap + heroku。我的诀窍是创造一个。带 cat yourcertificate.crt bundle.ca-bundle > server.crt的 crt 文件。然后打开这个文件,在第一个证书后添加一个换行符。你可以在

Https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl

安全地解决这个问题的另一种方法是使用以下模块。

Node _ tra _ ca _ certs _ mozilla _ bundle

通过生成一个包含 Mozilla 信任的所有根证书和中间证书的 PEM 文件,这个模块可以在不需要任何代码修改的情况下工作。你可以使用以下环境变量(适用于 Nodejs v7.3 +) ,

节点 _ EXTRA _ CA _ CERTS

生成与上述环境变量一起使用的 PEM 文件,您可以使用以下方法安装该模块:

npm install --save node_extra_ca_certs_mozilla_bundle

然后用环境变量启动节点脚本。

NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js

生成的 PEM 文件的其他使用方法可在以下网址获得:

Https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle

注意: 我是上述模块的作者。

你也可以尝试将 StrictSSL设置为 false,像这样:

{
url: "https://...",
method: "POST",
headers: {
"Content-Type": "application/json"},
strictSSL: false
}

如果因为使用节点 postgres/pg 模块而进入此线程,那么有一个比设置 NODE_TLS_REJECT_UNAUTHORIZEDrejectUnauthorized更好的解决方案,这将导致不安全的连接。

相反,配置“ ssl”选项以匹配 连接的参数:

{
ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
key: fs.readFileSync('/path/to/client-key.pem').toString(),
servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}

我编写了一个模块来帮助从环境变量(如 PGSSLROOTCERTPGSSLCERTPGSSLKEY)解析这些选项:

Https://github.com/programmarchy/pg-ssl

下面的命令对我很管用:

> npm config set strict-ssl false
> npm cache clean --force

问题在于,您试图从存储库中安装一个具有坏的或不受信任的 SSL [传输层安全]证书的模块。一旦清理了缓存,这个问题就会得到解决。以后你可能需要把它变成真的。

你好,只是这个主题的一个小补充,因为在我的情况下

require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

我没有工作,它不断返回错误的文件不能被下载我已经进入这个特定的错误研究了几个小时,当我遇到这个响应 https://stackoverflow.com/a/65442604

因为在我的应用程序中,我们有一个代理来代理我们的一些请求,作为我们的一些用户的安全要求,我发现在这种情况下,你正在咨询一个 API 有这个问题,如果你可以通过你的浏览器访问 API 的网址,你可以代理你的请求,它可能会修复[错误: UNABLE _ TO _ VERIFY _ LEAF _ SIGNATURE ]问题。

我如何使用代理的一个例子

await axios.get(url, {
timeout: TIME_OUT,
headers: {
'User-Agent': 'My app'
},
params: params,
proxy: {
protocol: _proxy.protocol,
host: _proxy.hostname,
port: _proxy.port,
auth: {
username: _proxy_username,
password: _proxy_password
}
}
});

我也有同样的问题,我可以用下面的方法来解决,

  1. 使用全链证书或只使用链证书,而不仅仅使用证书。

仅此而已。

在尝试从 npm 安装本地 git 共享 repo 时也会收到同样的错误。 错误将读取: npm ERR! 代码 UNABLE _ TO _ VERIFY _ LEAF _ SIGNATURE 显然,这个证书有一个问题,但是对我有效的方法是将 package.json 文件中指向我的共享回购的链接从: “共享前端”: “ https://myreposerver" ; 致: “共享前端”: “ git + https://myreposerver" ;

简而言之,只要在链接中添加 Git + 就可以解决这个问题。

节点可能打印该错误的另一个原因是后端连接/服务配置错误。

遗憾的是,节点错误没有说明它无法验证哪个证书[特性请求! ]

您的服务器可能有一个非常好的证书链安装客户端连接,甚至显示一个漂亮的挂锁在浏览器的 URL 栏,但是当服务器尝试连接到后端数据库使用不同的错误配置的证书,然后它可能会产生一个相同的错误。

我在一些供应商代码中遇到这个问题已经有一段时间了。将后端数据库连接从自签名更改为实际证书解决了这个问题。