Flutter安卓端请求服务器报CERTIFICATE_VERIFY_FAILED证书过期错误如何解决
问题根因
该报错为Let's Encrypt证书信任链兼容问题导致:站点SSL证书配置本身无误,但Flutter安卓端的证书校验逻辑和浏览器、PC端逻辑存在差异:
- 安卓7.0以下系统内置根证书列表未收录Let's Encrypt新根证书
ISRG Root X1,仅保留已过期的旧根证书DST Root CA X3,Flutter默认调用系统根证书池校验时会误判证书过期 - 部分高版本安卓设备若手动导入过过期的
DST Root CA X3证书,或HTTP客户端默认优先识别旧跨签信任链,也会触发该报错
解决方案
方案1:调整Caddy服务器证书链(优先推荐,无需修改客户端代码)
修改Caddy配置,强制签发优先使用ISRG Root X1为根的信任链,跳过旧跨签链:
在对应站点的Caddyfile配置块中添加以下配置:
tls { issuer acme { preferred_chain "ISRG Root X1" } }
配置修改完成后重启Caddy,重新签发证书即可生效。
方案2:客户端内置可信根证书(全安卓版本兼容)
如果需要兼容安卓7以下系统,可在Flutter项目内置ISRG Root X1根证书,手动指定HTTP客户端信任规则:
- 下载
ISRG Root X1的PEM格式证书,存入项目assets目录,在pubspec.yaml中声明该assets资源。 - 以Dio客户端为例,初始化时配置自定义校验逻辑:
import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/services.dart'; void initDio() async { final dio = Dio(); // 加载内置根证书 final rootCertData = await rootBundle.load('assets/isrg_root_x1.pem'); final rootCertPem = String.fromCharCodes(rootCertData.buffer.asUint8List()); (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) { client.badCertificateCallback = (X509Certificate cert, String host, int port) { // 匹配内置根证书则放行,其余走默认校验 if (cert.pem == rootCertPem) return true; return false; }; return client; }; }
方案3:临时关闭证书校验(仅开发调试使用,禁止生产环境启用)
开发阶段可临时关闭证书校验快速验证问题:
Dio配置示例:
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) { client.badCertificateCallback = (X509Certificate cert, String host, int port) => true; return client; };
系统原生HttpClient配置示例:
HttpClient client = HttpClient() ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
内容的提问来源于stack exchange,提问作者RailTracer
相关产品推荐
相关产品推荐

