使用ws.js建立WebSocket连接提示Certificate has expired报错如何解决
wss连接报"Certificate has expired"但服务器证书有效排查方案
环境前置说明
Node版本:12.12.69
ws版本:3.3.1
两个均为已停止维护的老旧版本,问题核心大概率和老版本的SSL证书校验逻辑、内置根证书列表过期有关,可按以下顺序排查:
1. 校验Node内置根证书是否覆盖服务器证书的签发CA
Node.js 12.x版本的内置根证书列表随版本发布固定,不会动态更新,2021年之后多个通用根证书(如Let's Encrypt的DST Root CA X3)已过期并从后续Node版本中移除,如果你的服务器证书由这类根证书签发,老版Node会直接判定证书过期。
验证命令:node -e 'const tls = require("tls"); console.log(tls.rootCertificates.includes("DST Root CA X3"))'
如果返回false即可确认是根证书缺失问题:
- 临时修复:启动进程时添加环境变量
NODE_EXTRA_CA_CERTS=./你的根证书文件路径.pem手动导入缺失的根证书 - 永久修复:升级Node.js到14.x以上LTS版本,同步升级ws到8.x以上稳定版本
2. 验证ws证书校验逻辑是否异常
ws@3.x版本存在证书链校验的已知bug,会误判带中间证书的证书链有效性。可临时关闭证书校验做验证:
const WebSocket = require('ws'); // 仅用于测试验证,生产环境禁止保留该配置,会存在安全风险 const socket = new WebSocket('wss://你的服务地址', { rejectUnauthorized: false });
如果测试时可以正常连接,说明是校验逻辑问题,正确修复方式为手动指定完整证书链:
const fs = require('fs'); const WebSocket = require('ws'); const socket = new WebSocket('wss://你的服务地址', { ca: fs.readFileSync('./你的服务完整证书链文件.pem') });
3. 排查本地环境异常
- 确认本地设备系统时间是否和网络时间同步,若系统时间偏差超过证书有效期范围,也会触发过期报错
- 排查网络是否存在代理、防火墙等中间人设备,这类设备可能会替换SSL证书,老版本Node无法识别私有CA签发的代理证书时也会报过期。可在同一网络环境下用浏览器访问对应服务的HTTPS地址,核对证书详情和服务器真实证书是否一致,若不一致需将代理根证书加入Node信任列表,或联系网络管理员将服务地址加白。
内容的提问来源于stack exchange,提问作者Mohsin Sethi
相关产品推荐
相关产品推荐

