You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:51:09