Nodejs https请求UNABLE_TO_GET_ISSUER_CERT_LOCALLY

pie*_*ara 6 ssl https node.js

操作系统: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);
});
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

同样精确的脚本运行了好几个月,我确信身份验证是正确的.今天是我第一次遇到这种情况.

哪个可能是导致此错误的原因?

pie*_*ara 13

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

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

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

            rejectUnauthorized: false
Run Code Online (Sandbox Code Playgroud)

对于https请求的选项,这种方式在证书出现问题时不会抛出异常.

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

  • 请参阅我的答案,为什么这足以“使它正常工作”,但它却使您的客户端应用程序遭受MitM攻击。 (2认同)
  • **不要这样做**。您正在使用SSL来确保安全,然后显式将其关闭,那么,为什么首先要打扰SSL?由于您的客户端不再可以确定服务器的身份,因此您正在向中间攻击者敞开大门。 (2认同)

zak*_*jan 13

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

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

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

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