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

Node.js+Express用pem生成自签证书遇CIPHER_MISMATCH问题求助

解决Node.js 10 + Express自签名证书SSL协议/套件不兼容问题

这个问题我之前帮朋友排查过,核心原因是现代浏览器已经全面禁用了老旧的SSL协议(比如SSLv3、TLSv1.0/1.1)和弱加密算法(比如SHA-1),而pem模块默认生成的证书配置、以及Node.js 10的HTTPS服务器默认设置,刚好不符合现代浏览器的安全要求。下面给你两个可行的解决方案:

方案1:调整pem和HTTPS服务器的配置

直接修改你现有的代码,给pem生成证书时指定强算法和必要的证书扩展,同时给HTTPS服务器限定兼容的协议和加密套件:

第一步:修改pem.createCertificate的参数

pem.createCertificate({
  days: 365,
  selfSigned: true,
  keyBits: 2048, // 至少2048位,推荐4096位增强安全性
  hash: 'sha256', // 用SHA-256替代被弃用的SHA-1
  // 手动指定证书配置,添加SAN(现代浏览器强制要求)和密钥用途
  config: [
    '[req]',
    'distinguished_name = req_distinguished_name',
    'x509_extensions = v3_ca',
    '[req_distinguished_name]',
    'commonName = your-server.local', // 替换成你的内网服务器域名或IP
    '[v3_ca]',
    // 添加SAN字段,支持多个IP/域名,比如你的内网IP和localhost
    'subjectAltName = IP:192.168.1.100, DNS:your-server.local, DNS:localhost',
    'keyUsage = digitalSignature, keyEncipherment',
    'extendedKeyUsage = serverAuth' // 指定证书用于服务器认证
  ].join('\n')
}, this.start);

第二步:修改HTTPS服务器的启动配置

在start方法里,给https.createServer添加明确的SSL协议和加密套件配置:

start(err, keys) {
  if (err) { throw err }
  
  const httpsOptions = {
    key: keys.serviceKey,
    cert: keys.certificate,
    minVersion: 'TLSv1.2', // 只启用现代浏览器支持的TLS 1.2及以上版本
    // 指定现代浏览器兼容的强加密套件
    ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384',
    honorCipherOrder: true // 优先使用服务器指定的安全套件
  };

  let server = https.createServer(httpsOptions, app);
  server.listen(port, () => console.log(`API/NG running on https://192.168.1.100:${port}`) );
}

方案2:直接用OpenSSL命令生成证书(更可靠)

如果pem模块的配置还是有问题,建议直接用系统自带的OpenSSL工具生成证书,再在代码中加载,这种方式更灵活可控:

第一步:在Linux服务器上生成证书

执行以下命令(替换成你的内网IP和域名):

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \
  -keyout server-key.pem \
  -out server-cert.pem \
  -subj "/CN=your-server.local" \
  -addext "subjectAltName=IP:192.168.1.100, DNS:your-server.local, DNS:localhost"

这个命令会生成私钥server-key.pem和证书server-cert.pem,放在当前目录。

第二步:在代码中加载证书

const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();

// 配置HTTPS选项
const httpsOptions = {
  key: fs.readFileSync('./server-key.pem'),
  cert: fs.readFileSync('./server-cert.pem'),
  minVersion: 'TLSv1.2',
  ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384',
  honorCipherOrder: true
};

// 启动HTTPS服务器
const server = https.createServer(httpsOptions, app);
server.listen(port, () => {
  console.log(`API/NG running on https://192.168.1.100:${port}`);
});

最后补充注意事项

  1. 信任证书:生成证书后,需要在客户端浏览器(或系统信任存储)中导入server-cert.pem,否则浏览器会提示"不安全",但不会再出现协议/套件不兼容的错误。
  2. Node.js版本:Node.js 10已经停止维护了,如果可能的话尽量升级到LTS版本(比如16.x或18.x),新版本的SSL配置更友好,安全性也更高。
  3. SAN字段:一定要确保证书的SAN字段包含你实际访问的IP或域名,否则浏览器会认为证书不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:26:41