将自定义 pemEncoded 应用于 httpsAgent 失败

问题描述 投票:0回答:1

我在尝试从

unable to verify the first certificate
获取响应时遇到问题
https://testcall.zerophone.us/janus/info

我尝试使用

get-ssl-certificate
包获取SSL证书,然后使用fs将pemEncoded写入
cert.pem
,并将其添加到httpsAgent。下面是我在初始化 Express 之前获取证书的代码:

let httpsAgent
const handleServerCert = () => {
    return new Promise((resolve, reject) => {
        sslCertificate.get('testcall.zerophone.us').then(function (certificate) {
            console.log('certificate', certificate)
            fs.writeFile('cert1.pem', certificate.pemEncoded, async (err) => {
                if (err) {
                    console.error('create cert failed: ' + err);
                    reject()
                } else {
                    console.log('created cert success!\n')
                    // https://stackoverflow.com/a/60020493/1308590
                    const certFile = path.resolve(__dirname, 'cert1.pem')
                    rootCas.addFile(certFile);
                    httpsAgent = new https.Agent({ ca: rootCas });
                    https.globalAgent.options.ca = rootCas;
                    resolve()
                }
            });
        }).catch(error => {
            console.log(`can not get server cert:${SERVER_URL} \nerror:  ${error}`)
            reject()
        });
    })
}
const getAgent = () => {
    return httpsAgent
}

module.exports = {
    handleServerCert,
    getAgent
}

在initExpress之后,我使用全局方法将httpsAgents添加到请求中:

static defaultHeader() {
        return {
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            agent: getAgent()
        }
    }

但是我仍然遇到错误

unable to verify the first certificate
,我不知道为什么我仍然遇到这个问题,但是如果我从chorme打开网站,然后导出证书,使用这个,一切正常。有人可以帮助我了解我的问题吗?

node.js ssl-certificate
1个回答
0
投票

正如您引用的答案正确所说,您需要将中间 CA 证书(又名链 [CA] 证书) 添加到您的本地信任库。

get-ssl-certificate
没有获得中级CA证书,或任何CA证书;它只获得且始终是 server 又名叶证书。这对于形成信任链没有任何帮助。

像 Chrome 这样的 OTOH 浏览器,正如答案正确所说,通常可以获取丢失的证书(主要是在这里使用 AIA)。如果您从浏览器导出intermediate(不是叶)证书并将其添加到代码中,那就可以了。使用 OpenSSL 和curl 的答案中显示的方法也是如此。或者如果您想要代码:

// I'm not a promiser so that's left as an exercize, plus whatever errorhandling you want
const tls = require('tls'), http  = require('http'), fs = require('fs');

function pemEncode(b,l){ return "-----BEGIN "+l+"-----\n"
  + b.toString('base64').replace(/.{64}/g,'$&\n')
  + "\n-----END "+l+"-----\n";
}
function getCert(u){ http.get(u, (res)=>{ var d=[];
  res.on('data',(chunk)=>{ d.push(chunk) });
  res.on('end',()=>{ fs.writeFileSync('cert1.pem',pemEncode(Buffer.concat(d),'CERTIFICATE')) });
  });
}
var host = 'testcall.zerophone.us', port = 443;
// many servers today require SNI to get their cert (or anything else),
// in which case add servername:host, but this one doesn't
const s = tls.connect( {host,port,rejectUnauthorized:false}, ()=>{
  getCert( s.getPeerCertificate().infoAccess['CA Issuers - URI'][0]);
  s.destroy() });
© www.soinside.com 2019 - 2024. All rights reserved.