Node.js NodeJS tls.connect()getPeerCertificate()返回错误(多个),但浏览器显示正常

Node.js NodeJS tls.connect()getPeerCertificate()返回错误(多个),但浏览器显示正常,node.js,ssl,tls1.2,Node.js,Ssl,Tls1.2,我正在构建一个SSL爬虫应用程序,其中用户传入域名,NodeJ使用tls库检索SSL证书 首先,这是我的代码: server.js const tls = require('tls'); var rootCas = require('ssl-root-cas/latest').create(); const fs = require('fs'); fs.readdirSync('./keys/intermediate_certs').forEach(file => { rootC

我正在构建一个SSL爬虫应用程序,其中用户传入域名,NodeJ使用
tls
库检索SSL证书

首先,这是我的代码:

server.js

const tls = require('tls');
var rootCas = require('ssl-root-cas/latest').create();
const fs = require('fs');

fs.readdirSync('./keys/intermediate_certs').forEach(file => {
    rootCas.addFile('./keys/intermediate_certs/' + file)
});

var secureContext = tls.createSecureContext({
    ca: rootCas
});

options = {
    host: host, //domain like google.com
    port: 443,
    secureContext: secureContext,
    ca: rootCas,
    rejectUnauthorized: true
};

var tlsSocket = tls.connect(options, function () {

   let rawCert = tlsSocket.getPeerCertificate()
   console.log(rawCert)
})

tlsSocket.on('error', (error) => {
   console.log(error)
   // [ERR_TLS_CERT_ALTNAME_INVALID] Hostname/IP does not match certificate's altnames: Host: zdns.cn. is not in the cert's altnames: DNS:*.fkw.com, DNS:fkw.com

   // unable to verify the first certificate or UNABLE_TO_VERIFY_LEAF_SIGNATURE
});
问题是nodejs应用程序抛出错误,根据
TLS
文档,错误来自OpenSSL,但是,当浏览网站时,
view certificate
显示所有有效的(甚至公共名称完全匹配)

以下是一些标准:

  • zdns.cn/www.zdns.cn正在显示错误:
    ERR\u TLS\u CERT\u ALTNAME\u INVALID
    ;从浏览器中查看证书时,会显示
    *.zdns.cn
  • knet.cn/www.knet.cn显示错误:
    无法验证第一个证书
    ;从浏览器查看证书时,会显示
    www.knet.cn

  • 注意:我从
    ssl根CA
    中包含了最新的根CA,并且还从CA站点手动下载了
    中间证书。

    您得到该错误的具体原因是您的
    参数。证书以CN的形式呈现
    *.fkw.com
    ,并以备选名称呈现
    *.fkw.com
    fkw.com
    。这些都不符合
    zdns.cn
    www.zdns.cn


    如果您只是为了获取证书而爬行,则可能需要删除
    拒绝未经授权的
    。或者,该错误似乎显示了错误中的其余证书信息。因此,您可以保持原样,并在输出中包含有关证书不受信任/无效原因的信息。对于获取证书的爬虫来说,这似乎是很有价值的信息。

    您能提供您正在使用的nodejs版本吗?文件
    ssl root cas/latest
    的一个示例也很好,我不确定NodeJS中的实现,但我遇到过其他主机名验证程序,它们没有很好地检查备用名称。请查看以下答案:。您可以覆盖checkServerIdentity以忽略它,或者实现一个更健壮的适用于您的方法。老实说,如果您只是对证书进行爬网,您可能希望跳过证书上的所有主机名和其他验证,可能需要手动查看它们并将结果添加到输出中。