Node.js添加自定义证书到httpsAgent仍报unable to verify the first certificate
解决Node.js请求
https://testcall.zerophone.us/janus/info时的unable to verify the first certificate错误 问题核心原因
你通过get-ssl-certificate获取的证书仅包含服务器叶子证书,缺少完整的证书链(中间CA证书)。而Chrome导出的证书会自动包含整个信任链,因此能通过验证。
排查与解决步骤
1. 对比证书内容差异
打开代码生成的cert1.pem和Chrome导出的证书文件:
- Chrome导出的文件会包含多个
-----BEGIN CERTIFICATE-----至-----END CERTIFICATE-----的证书块(服务器证书+中间CA证书) - 代码生成的
cert1.pem大概率只有单个证书块
2. 手动获取完整证书链
用OpenSSL命令获取目标域名的完整信任链:
openssl s_client -connect testcall.zerophone.us:443 -showcerts > full_chain.pem
将命令输出的所有证书内容(从第一个-----BEGIN CERTIFICATE-----到最后一个-----END CERTIFICATE-----)保存到full_chain.pem文件中。
3. 修改代码加载完整证书链
替换原证书处理逻辑,直接使用完整链文件:
const https = require('https'); const path = require('path'); const rootCas = require('ssl-root-cas').create(); let httpsAgent; const handleServerCert = () => { return new Promise((resolve, reject) => { try { const certFile = path.resolve(__dirname, 'full_chain.pem'); rootCas.addFile(certFile); httpsAgent = new https.Agent({ ca: rootCas }); https.globalAgent.options.ca = rootCas; console.log('完整证书链加载成功'); resolve(); } catch (err) { console.error('加载证书链失败:', err); reject(err); } }); }; const getAgent = () => httpsAgent; module.exports = { handleServerCert, getAgent };
4. 确保证书链加载时机正确
在Express初始化和发起请求前,必须确保证书链已加载完成:
async function startServer() { await handleServerCert(); // 初始化Express并启动服务 app.listen(3000, () => console.log('服务器启动成功')); } startServer();
5. 验证证书链有效性
用OpenSSL确认证书链是否合法:
openssl verify -CAfile full_chain.pem full_chain.pem
输出OK则表示证书链有效。
内容的提问来源于stack exchange,提问作者famfamfam
相关产品推荐
相关产品推荐

