# SSL_ERROR_HANDSHAKE_FAILURE_ALERT：Firefox 握手失败怎么办

> SSL_ERROR_HANDSHAKE_FAILURE_ALERT 表示服务器主动中止了 TLS 握手，Firefox 只能显示“建立安全连接失败”。最常见的是要求客户端证书或加密套件过旧。

Source: https://ssl.sh/zh/errors/ssl-error-handshake-failure-alert/
Last updated: 2026-11-10

**SSL_ERROR_HANDSHAKE_FAILURE_ALERT 的意思是：服务器用一条 `handshake_failure` 警报结束了 TLS 握手。** Firefox 显示“建立安全连接失败”，正文是“连接到 example.com 时发生错误。SSL 对等端无法协商出一个可接受的安全参数设置。”服务器不说具体原因，最常见的两个是：服务器要求客户端证书而 Firefox 没有发送；或者服务器只接受 Firefox 已经不再提供的老旧加密套件。

## 这个警报是什么意思

这是服务器发出的 40 号警报，表示它无法和 Firefox 协商出可接受的安全参数。TLS 服务器遇到致命问题时会发送带编号的警报，TLS 1.3 现行规范 RFC 9846 对 `handshake_failure`（40）的定义是：发送方在可选范围内“无法协商出一组可接受的安全参数”。Firefox 使用的 TLS 库 NSS 把这个警报映射为 `SSL_ERROR_HANDSHAKE_FAILURE_ALERT`。

| Firefox 错误代码 | 谁发现的问题 |
|---|---|
| `SSL_ERROR_HANDSHAKE_FAILURE_ALERT` | 服务器，发送了 `handshake_failure` |
| [SSL_ERROR_NO_CYPHER_OVERLAP](https://ssl.sh/zh/errors/ssl-error-no-cypher-overlap/) | Firefox 自己，找不到共同套件 |
| `SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT` | 服务器，发送了 TLS 1.3 的 `certificate_required` |
| [SSL_ERROR_UNSUPPORTED_VERSION](https://ssl.sh/zh/errors/ssl-error-unsupported-version/) | 协议版本不匹配 |

同样的服务器行为在 Chrome 里通常显示为 [ERR_SSL_VERSION_OR_CIPHER_MISMATCH](https://ssl.sh/zh/errors/err-ssl-version-or-cipher-mismatch/)，涉及客户端证书时显示为 [ERR_BAD_SSL_CLIENT_AUTH_CERT](https://ssl.sh/zh/errors/err-bad-ssl-client-auth-cert/)。

## 先判断是不是只有你打不开

换浏览器、换网络、从外部检测，这三步能定位原因：哪一步之后能打开，原因就在哪一步。

1. **换个浏览器。** Chrome、Edge 能打开而 Firefox 不行，多半是客户端证书或 Firefox 自身设置的问题，看下面第 1、3 条。
2. **换个网络。** 用手机热点能打开、公司网络不行，说明中间的代理或防火墙在干扰，看第 4 条。
3. **从外部检测网站。** 用 [SSL 检测](https://ssl.sh/zh/tools/ssl-checker/) 测一下，外部也握手失败，就是服务器配置问题，只能联系网站管理员。

这个页面没有“接受风险并继续”按钮：握手没有完成，不存在可以继续使用的连接。

## 常见原因（按出现频率排序）

这个警报有 5 种常见原因，最常见的是服务器要求客户端证书而 Firefox 没有发送。

### 1. 服务器要求客户端证书

企业门户、政务系统、银行后台、VPN 网关经常要求[双向 TLS](https://ssl.sh/zh/learn/mtls/)。Firefox 没发证书，强制要求证书的 OpenSSL 系服务器就会中止握手。OpenSSL 在 TLS 1.2 连接上会把 TLS 1.3 的 `certificate_required` 警报换成 `handshake_failure`，所以走 TLS 1.2 时看到的恰好就是这个错误。

确认服务器是否在要客户端证书：

```bash
openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null 2>/dev/null \
  | sed -n '/Acceptable client certificate CA names/,/Requested Signature/p'
```

输出了一串 CA 名称，说明服务器在请求客户端证书。Apache 用 `SSLVerifyClient require` 就是这种效果；Nginx 的 `ssl_verify_client on;` 则会先完成握手、再返回 HTTP 400，不会出现这个错误。

Firefox 这边：90 及以后的版本会自动到 Windows 和 macOS 的系统证书库里找客户端证书；放在智能卡或 USB Key 里的证书，需要在“设置 > 隐私与安全 > 安全设备”里加载厂商提供的 PKCS#11 模块；过期的个人证书等同于没有证书。

国内还有一种情况：不少网银、政务、办公系统靠 USB Key 做客户端认证，配套的控件和驱动往往只适配 IE 内核。360 官方的说明里也写到，双核浏览器的 IE 内核主要就是为这类网站保留的。遇到这种系统，按网站要求使用指定浏览器或兼容模式，比折腾 Firefox 更省事。

### 2. 服务器只接受老旧的加密套件

老设备、嵌入式管理界面、长期没更新的服务器，可能只接受现在 Firefox 已经不再提供的套件。看看服务器接受什么：

```bash
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -brief </dev/null
nmap --script ssl-enum-ciphers -p 443 example.com
```

如果只列出老的 CBC 或 3DES 套件，就必须升级服务器。具体套件可以用 [加密套件查询](https://ssl.sh/zh/tools/cipher-suite-lookup/) 查。

### 3. Firefox 的 TLS 设置被改过

一些加固教程和扩展会修改 `about:config` 里的 `security.ssl3.*` 或 `security.tls.version.*`。如果关掉了服务器需要的套件，服务器就会回这个警报。新建一个干净的配置文件测试（地址栏输入 `about:profiles`，新建配置文件）；新配置文件里正常，就把改过的首选项恢复默认。

### 4. 中间有安全软件或代理

杀毒软件的 HTTPS 扫描和公司代理会自己终止 TLS。如果它们对外连接用的配置过时，上游服务器会拒绝它们，警报再被转给 Firefox。临时关闭 HTTPS 扫描或换个网络就能判断，详见 [杀毒软件 HTTPS 扫描](https://ssl.sh/zh/errors/antivirus-https-scanning-ssl-error/)。

### 5. TLS 终止设备上没配这个域名

有些负载均衡和 CDN 在没有对应域名证书时，不发 `unrecognized_name`，而是直接发一个笼统的失败警报。把上面的 `openssl s_client` 命令分别带和不带 `-servername` 跑一次对比。

## 怎么修

用户这边要让 Firefox 能找到并发送个人证书；服务器这边要开启 TLS 1.2/1.3 和现代套件，并给每个域名配好证书。

**需要个人证书的网站用户：**
1. 把 Firefox 升级到最新版本。
2. 把证书装进系统证书库，或者在“设置 > 隐私与安全 > 证书 > 查看证书 > 您的证书”里导入 `.p12`/`.pfx` 文件。
3. 智能卡、USB Key 用户，在“安全设备”里加载厂商的 PKCS#11 模块。
4. 刷新页面，Firefox 弹窗时选择对应证书。

**服务器管理员：**
- 开启 TLS 1.2 和 1.3，使用 ECDHE 加 AES-GCM 或 CHACHA20 的套件；[TLS 配置生成器](https://ssl.sh/zh/tools/tls-config-generator/) 可以直接生成可用配置。
- 如果只有部分用户需要客户端证书，Apache 用 `SSLVerifyClient optional`、Nginx 用 `ssl_verify_client optional;`，在应用里处理没带证书的情况，用户就能看到一个可读的提示页，而不是握手直接失败。
- 每台 TLS 终止设备上都要给每个域名配好证书。

## 怎么确认已经修好

openssl 能完成握手、Firefox 重新打开不再报错，就说明修好了。

1. `openssl s_client -connect example.com:443 -servername example.com -brief` 能完成握手，打印出协议和套件。
2. 双向 TLS 的，带上客户端证书测试：`openssl s_client -connect example.com:443 -servername example.com -cert client.pem -key client.key -brief`。
3. 用 Firefox 重新打开网站；[SSL 检测](https://ssl.sh/zh/tools/ssl-checker/) 可以从外部确认服务器一侧是否正常。
