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
相关产品推荐
相关产品推荐

