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

Node.js如何从主机名或PEM文件获取完整SSL证书链(叶到根)

在Node.js中获取完整SSL证书链(叶到根)

问题背景

现有Node.js代码仅能获取根证书,无法拿到从叶子到根的完整证书链,而Go语言通过ConnectionState().PeerCertificates可正常获取完整链。以下是针对两种场景的解决方案:


一、从主机名获取完整证书链

Node.js的tls.connect()中,getPeerCertificate()默认仅返回叶子证书,要获取完整链需使用**getPeerCertificates()(复数形式)**,同时配置rejectUnauthorized: false跳过证书验证(和Go的InsecureSkipVerify对应)。

修正后的代码:

const tls = require('tls');

const conf = {
  rejectUnauthorized: false // 对应Go的InsecureSkipVerify
};

const conn = tls.connect(443, 'www.facebook.com', conf, () => {
  // 获取完整证书链(顺序:叶子 → 中间 → 根)
  const certChain = conn.getPeerCertificates();
  
  console.log('完整证书链:');
  certChain.forEach((cert, index) => {
    console.log(`\n证书 ${index + 1}:`);
    console.log(`DNS名称: ${cert.subjectaltname || cert.subject.CN}`);
    console.log(`通用名称: ${cert.subject.CN}`);
    console.log(`颁发者: ${cert.issuer.CN}`);
    console.log(`有效期至: ${cert.valid_to}`);
    console.log(`有效期从: ${cert.valid_from}`);
    console.log(`序列号: ${cert.serialNumber}`);
    console.log(`签名算法: ${cert.signatureAlgorithm}`);
  });
  
  conn.end();
});

conn.on('error', (err) => {
  console.error('连接错误:', err);
});

conn.on('close', () => {
  console.log('\n连接已关闭');
});

二、从PEM文件或x5u URL获取完整证书链

x5u URL返回的通常是多个PEM格式证书拼接的内容,需先分割每个独立证书块,再逐个解析为X509Certificate实例,组成完整链。

修正后的代码:

const axios = require('axios');
const { X509Certificate } = require('crypto');

async function getCertChainFromX5u(x5uUrl) {
  try {
    const response = await axios.get(x5uUrl);
    const pemContent = response.data;
    
    // 分割PEM证书块(匹配-----BEGIN CERTIFICATE-----到-----END CERTIFICATE-----的内容)
    const pemCerts = pemContent.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g);
    
    if (!pemCerts) {
      throw new Error('未找到有效的PEM证书');
    }
    
    // 解析每个证书并组成链
    const certChain = pemCerts.map(pem => {
      const cert = new X509Certificate(pem);
      return cert.toLegacyObject();
    });
    
    console.log('从x5u获取的完整证书链:');
    certChain.forEach((cert, index) => {
      console.log(`\n证书 ${index + 1}:`);
      console.log(`通用名称: ${cert.subject.CN}`);
      console.log(`颁发者: ${cert.issuer.CN}`);
      console.log(`有效期至: ${cert.valid_to}`);
      console.log(`有效期从: ${cert.valid_from}`);
      console.log(`序列号: ${cert.serialNumber}`);
    });
    
    return certChain;
  } catch (err) {
    console.error('获取证书链失败:', err);
  }
}

// 调用示例
getCertChainFromX5u('https://example.com/x5u-url');

关键说明

  • Node.js中getPeerCertificates()返回的证书链顺序为叶子证书在前,根证书在后,和Go的PeerCertificates一致。
  • 处理PEM内容时,必须分割独立证书块,否则X509Certificate只会解析第一个证书。

内容的提问来源于stack exchange,提问作者Pinank Lakhani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:42:50