Nodejs https请求UNABLE_TO_GET_ISSUER_CERT_LOCALLY

时间:2015-06-04 18:26:43

标签: node.js ssl https

操作系统:debian sid

Nodejs:v0.10.38

我向使用身份验证的私人服务发出请求:

var https = require('https');

var options = {
    host: 'private.service.com',
    path: '/accounts/' + '123323' + '/orders',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': 0,
        'Authorization': 'Bearer ' + 'asdsdgcvxcvxcv'
    }
};

var request = https.request(options, function (res) {
    console.log(res);
});

当我运行脚本时,节点会抛出此错误:

events.js:72
    throw er; // Unhandled 'error' event
          ^
Error: UNABLE_TO_GET_ISSUER_CERT_LOCALLY
    at SecurePair.<anonymous> (tls.js:1381:32)
    at SecurePair.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:980:10)
    at CleartextStream.read [as _read] (tls.js:472:13)
    at CleartextStream.Readable.read (_stream_readable.js:341:10)
    at EncryptedStream.write [as _write] (tls.js:369:25)
    at doWrite (_stream_writable.js:226:10)
    at writeOrBuffer (_stream_writable.js:216:5)
    at EncryptedStream.Writable.write (_stream_writable.js:183:11)
    at write (_stream_readable.js:602:24)

同样精确的脚本在数月内运行良好,我确信身份验证是正确的。今天是我第一次遇到这种情况。

导致此错误的原因可能是什么?

5 个答案:

答案 0 :(得分:12)

经过一番研究后,我发现这是服务器的问题,我正在尝试向https请求。

节点https无法在private.service服务器上找到ssl ISSUER_CERT,因此会抛出该异常。

我使用的解决方案,因为我确信我可以信任该服务器,是添加

            rejectUnauthorized: false

到https请求的选项,这样节点在证书出现问题时不会抛出异常。

无论如何,只有当您知道可以信任您的请求主机时,此解决方案才有效,否则它可能不是最佳解决方案。

答案 1 :(得分:10)

SSL有原因。除了其他功能外,它还会验证您是否真正与private.service.com主机名标识的服务器进行通信。否则,您的客户端软件可能会受到中间人攻击的欺骗。

首先,当遇到此问题时,他们应该更新系统根SSL证书。在Debian中,它们包含在ca-certificates apt-get包中。

如果没有帮助,服务器可能会使用颁发者证书,默认情况下全球PKI基础架构不信任该证书。在这种情况下,客户端应将证书公钥签名与预共享值进行比较。这被称为“证书固定”。

特别是对于您的错误,如果之前有效,则服务器证书可能已过期。服务器应该更新它。作为临时解决方案,您可以通过rejectUnauthorized选项关闭PKI验证。但是,您应该将其与固定方法一起使用。在NodeJS中,您可以从res.socket.getPeerCertificate().fingerprint获取服务器证书指纹。

答案 2 :(得分:2)

经过研究后,这解决了问题:

npm set strict-ssl=false

希望它有所帮助。

答案 3 :(得分:1)

this GitHub issue中,使用以下环境变量:

export NODE_EXTRA_CA_CERTS=/path/to/certfile.crt

此后,您可以运行任何npm命令,nodejs将信任您的额外证书文件。

.crt文件是包含前缀行,base64编码的证书和后缀行的文件。

如果您没有根CA证书,则可以使用openssl命令从URL生成证书文件:

openssl s_client \
    -showcerts \
    -servername <host> \
    -connect <host>:443 2>/dev/null </dev/null | \
  openssl x509

<host>是URL的主机名。例如,使用google.com作为主机,输出看起来像这样:

-----BEGIN CERTIFICATE-----
MIIIIDCCBwigAwIBAgIQI/1aCHwDN94QFUhXJeIwODANBgkqhkiG9w0BAQsFADBU
(42 more lines)
E+Hv1bJSbOMSNCDzqRM3JUzvM6Y=
-----END CERTIFICATE-----

将其另存为.crt文件,并将其路径添加到NODE_EXTRA_CA_CERTS环境变量中,就一切就绪。

答案 4 :(得分:-1)

当我尝试在Ubuntu 16上安装npm时,我得到了同样的错误。 以下命令对我有用。

npm config set registry http://registry.npmjs.org/