【发布时间】:2020-08-23 02:59:48
【问题描述】:
我正在构建一个 SSL 爬虫应用程序,其中用户传入域名,NodeJS 使用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_TLS_CERT_ALTNAME_INVALID;从浏览器查看证书时显示*.zdns.cn - knet.cn / www.knet.cn 显示错误:
unable to verify the first certificate;从浏览器查看证书时显示www.knet.cn
注意:我包含了来自 ssl-root-cas 的最新根 CA,还从 CA 站点手动下载了 intermediate certificate。
【问题讨论】:
-
能否提供您正在使用的nodejs版本?文件
ssl-root-cas/latest的示例也很好 -
我不确定 NodeJS 中的实现,但我遇到过其他不能很好地检查备用名称的主机名验证器。看看这个答案:stackoverflow.com/questions/47849427/…。您可以覆盖
checkServerIdentity以忽略它,或者实现一个更强大的适合您的方法。老实说,如果您只是抓取证书,您可能希望跳过证书上的所有主机名和其他验证,可能需要手动查看它们并将结果添加到您的输出中。