无法验证叶签名

时间:2013-11-19 21:54:24

标签: javascript node.js ssl request

我正在使用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,这是为什么?是否需要在服务器上运行?

15 个答案:

答案 0 :(得分:122)

注意:以下内容很危险,并允许在客户端和服务器之间拦截和修改API内容。

这也有效

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

答案 1 :(得分:81)

这不是应用程序的问题,而是由中间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);
});

答案 2 :(得分:64)

安全解决方案

您可以向链中添加必要的证书,而不是关闭安全性。首先从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

另外,请参阅下面的答案

答案 3 :(得分:40)

CoolAJ86的解决方案是正确的,它不会影响您的安全性,例如使用rejectUnauthorizedNODE_TLS_REJECT_UNAUTHORIZED禁用所有检查。不过,您可能需要明确注入额外的CA证书。

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

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

我仍然遇到UNABLE_TO_VERIFY_LEAF_SIGNATURE错误。然后我发现谁为COMODO SSL Analyzer所连接的网站颁发了证书,下载了该权限的证书,并试图只添加那个:

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');

答案 4 :(得分:4)

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

答案 5 :(得分:3)

您还可以尝试将{strong> strictSSL 设置为false,如下所示:

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

答案 6 :(得分:2)

我有同样的问题。我已经关注了@ThomasReggi和@ CoolAJ86解决方案并且运行良好,但我对解决方案不满意。

因为&#34; UNABLE_TO_VERIFY_LEAF_SIGNATURE&#34;由于认证配置级别而发生问题。

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

enter image description here

答案 7 :(得分:1)

只是把它放在这里,以防它帮助某人,我的情况不同,有点奇怪的混合。我通过superagent访问的请求得到了这个问题 - 问题与证书(设置正确)无关,而这与我当时通过{{传递超级结果 - 这一事实有关。 3}}模块的瀑布回调。要修复:只需将result.body传递给瀑布的回调,而不是传递整个结果。

答案 8 :(得分:1)

对于 Create React App (也会发生此错误,并且此问题是Google排名第一的问题),您可能使用HTTPS=true npm startproxy(在{ {1}})在开发中时,会转到一些本身是自签名的HTTPS API。

如果是这种情况,请考虑像这样更改package.json

proxy

"proxy": { "/api": { "target": "https://localhost:5001", "secure": false } } 决定WebPack代理是否检查证书链,并禁用以确保未验证API自签名证书,以便获取数据。

答案 9 :(得分:1)

在请愿书中放入 rejectUnauthorized:false ,对我有用。

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

您必须在服务器中包含中间证书。这样可以解决[错误:UNABLE_TO_VERIFY_LEAF_SIGNATURE]

答案 12 :(得分:0)

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

node_extra_ca_certs_mozilla_bundle

该模块可以通过生成包含Mozilla信任的所有根证书和中间证书的PEM文件而无需进行任何代码修改即可工作。您可以使用以下环境变量(适用于Nodejs v7.3 +),

NODE_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

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

答案 13 :(得分:0)

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

相反,配置“ ssl”选项以匹配tls.connect的参数:

{
  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

答案 14 :(得分:-2)

以下命令对我有用:

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

问题是您正试图从存储库中使用错误或不受信任的SSL [安全套接字层]证书安装模块。清理缓存后,此问题将得到解决。您可能需要稍后将其设置为true。