操作系统应用开发(二十九)RustDesk错误修复——东方仙盟筑基期

CERTIFICATE_VERIFY_FAILED: certificate has expired(../../flutter/third_party/boringssl/src/ssl/handshake.cc:393))

无法拉去通讯录和添加地址无法登录

是sll到期更新证书即可

错误栈原文:

复制代码
CERTIFICATE_VERIFY_FAILED: certificate has expired(../../flutter/third_party/boringssl/src/ssl/handshake.cc:393)

一证书位置

文件路径:flutter/third_party/boringssl/src/ssl/handshake.cc

关键校验片段(行 393 附近证书有效期校验逻辑)

复制代码
// 执行对等方证书链校验
enum ssl_verify_result_t SSLHandshake::VerifyPeerCertificate() {
  bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
  if (!ctx) {
    return ssl_verify_internal_error;
  }

  X509_STORE_CTX_init(ctx.get(), ssl_ctx_->x509_store(), peer_cert_.get(), nullptr);
  // 传入完整证书链
  for (const auto &cert : peer_cert_chain_) {
    X509_STORE_CTX_set0_chain(ctx.get(), cert.get());
  }

  // 核心校验入口:校验证书有效期、签名、信任链、域名等
  int verify_ret = X509_verify_cert(ctx.get());
  if (verify_ret <= 0) {
    int err = X509_STORE_CTX_get_error(ctx.get());
    // 错误分支:证书过期
    if (err == X509_V_ERR_CERT_HAS_EXPIRED) {
      // 对应报错字符串输出:CERTIFICATE_VERIFY_FAILED: certificate has expired
      ssl_->error_code_ = SSL_ERROR_CERTIFICATE_VERIFY_FAILED;
      ssl_->error_string_ = "certificate has expired";
      // 报错输出点:handshake.cc 393 行
      return ssl_verify_cert_invalid;
    }
    // 其他证书错误:未信任、域名不匹配、签名无效等
    ssl_->error_code_ = SSL_ERROR_CERTIFICATE_VERIFY_FAILED;
    ssl_->error_string_ = X509_STORE_CTX_get_error_string(ctx.get());
    return ssl_verify_cert_invalid;
  }

  // 额外域名校验
  if (!CheckHostname(ctx.get())) {
    ssl_->error_code_ = SSL_ERROR_CERTIFICATE_VERIFY_FAILED;
    ssl_->error_string_ = "hostname mismatch";
    return ssl_verify_cert_invalid;
  }

  return ssl_verify_ok;
}

关键常量说明

复制代码
// boringssl/include/openssl/x509_vfy.h
#define X509_V_ERR_CERT_HAS_EXPIRED 10 /* 证书已过期 */

X509_verify_cert 返回失败且错误码 = 10,就抛出你看到的日志。

二、RustDesk Flutter 上层封装代码(触发 BoringSSL 调用逻辑)

RustDesk Flutter 网络层基于 Dart HttpClient,底层绑定 Flutter BoringSSL,连接中继 / 控制服务器时触发 TLS 握手:

Dart 网络请求片段(rustdesk_flutter/lib/services/network.dart

复制代码
import 'dart:io';

Future<Socket> connectRustDeskRelay(String host, int port) async {
  try {
    // TLS加密连接,底层走Flutter内置BoringSSL
    SecureSocket socket = await SecureSocket.connect(
      host,
      port,
      // 未关闭证书校验时,会触发BoringSSL证书校验逻辑
      onBadCertificate: (X509Certificate cert) {
        // 默认返回false,拒绝过期/无效证书,抛出CERTIFICATE_VERIFY_FAILED
        return false;
      },
    );
    return socket;
  } on SocketException catch (e) {
    // 捕获BoringSSL底层抛出的证书错误
    if (e.message.contains("CERTIFICATE_VERIFY_FAILED: certificate has expired")) {
      throw Exception("中继服务器SSL证书过期:${e.message}");
    }
    rethrow;
  }
}

三、RustDesk Rust 后端原生 TLS 校验(另一套触发同源错误代码)

RustDesk 核心服务端 / 桌面端使用 rustls,同样会报证书过期逻辑,补充源码:

复制代码
use rustls::{ClientConfig, RootCertStore, ServerName};
use std::net::TcpStream;
use std::sync::Arc;

fn tls_connect(host: &str, port: u16) -> Result<(), Box<dyn std::error::Error>> {
    let mut root_store = RootCertStore::empty();
    root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
        rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
            ta.subject, ta.spki, ta.name_constraints
        )
    }));

    let config = ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_store)
        .with_no_client_auth();

    let tcp = TcpStream::connect((host, port))?;
    let server_name = ServerName::try_from(host).unwrap();
    let conn = rustls::ClientConnection::new(Arc::new(config), server_name)?;
    
    // TLS握手,校验证书有效期
    let mut tls_stream = rustls::Stream::new(conn, tcp);
    tls_stream.flush()?;

    // 证书过期错误匹配
    // rustls错误枚举:Error::InvalidCertificate(CertificateError::Expired)
    Ok(())
}

四、错误出现完整链路

  1. Flutter App 发起 SecureSocket.connect TLS 连接 RustDesk 中继服务器
  2. Flutter 底层调用内置 BoringSSL 执行握手(handshake.cc
  3. BoringSSL 调用X509_verify_cert校验证书时间
  4. 证书notAfter时间早于设备当前系统时间 → 错误码X509_V_ERR_CERT_HAS_EXPIRED
  5. 393 行分支赋值错误字符串,向上抛出 SSL 校验失败异常
  6. Dart 层捕获 SocketException,打印日志:CERTIFICATE_VERIFY_FAILED: certificate has expired

五、临时绕过校验代码(测试用,生产禁止)

Dart Flutter 绕过过期证书

复制代码
SecureSocket.connect(
  host,
  port,
  onBadCertificate: (cert) => true, // 强制信任所有异常证书(过期、自签)
);

Rust 后端绕过证书校验(仅本地调试)

复制代码
// 不安全配置,跳过证书有效期校验
let config = ClientConfig::builder()
    .with_custom_certificate_verifier(Arc::new(NoOpVerifier))
    .with_no_client_auth();

struct NoOpVerifier;
impl rustls::client::ServerCertVerifier for NoOpVerifier {
    fn verify_server_cert(
        &self, _end_entity: &rustls::Certificate, _intermediates: &[rustls::Certificate],
        _server_name: &ServerName, _scts: &mut dyn Iterator<Item = &[u8]>,
        _ocsp_response: &[u8], _now: std::time::SystemTime
    ) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
        Ok(rustls::client::ServerCertVerified::assertion())
    }
}

六、根本修复方案

  1. 服务端:更新 RustDesk 中继 / 后台 SSL 证书,重新签发有效证书
  2. 客户端:校准设备系统时间(设备时间错乱会误判证书过期)
  3. 编译侧:升级 Flutter 版本,同步更新内置 BoringSSL 根证书库
  4. 私有化部署:替换自有有效 CA 证书,关闭公共过期证书依赖

人人皆为创造者,共创方能共成长

每个人都是使用者,也是创造者;是数字世界的消费者,更是价值的生产者与分享者。在智能时代的浪潮里,单打独斗的发展模式早已落幕,唯有开放连接、创意共创、利益共享,才能让个体价值汇聚成生态合力,让技术与创意双向奔赴,实现平台与伙伴的快速成长、共赢致远。

原创永久分成,共赴星辰大海

原创创意共创、永久收益分成,是东方仙盟始终坚守的核心理念。我们坚信,每一份原创智慧都值得被尊重与回馈,以永久分成锚定共创初心,让创意者长期享有价值红利,携手万千伙伴向着科技星辰大海笃定前行,拥抱硅基 生命与数字智能交融的未来,共筑跨越时代的数字文明共同体。

东方仙盟:拥抱知识开源,共筑数字新生态

在全球化与数字化浪潮中,东方仙盟始终秉持开放协作、知识共享的理念,积极拥抱开源技术与开放标准。我们相信,唯有打破技术壁垒、汇聚全球智慧,才能真正推动行业的可持续发展。

开源赋能中小商户:通过将前端异常检测、跨系统数据互联等核心能力开源化,东方仙盟为全球中小商户提供了低成本、高可靠的技术解决方案,让更多商家能够平等享受数字转型的红利。

共建行业标准:我们积极参与国际技术社区,与全球开发者、合作伙伴共同制定开放协议 与技术规范,推动跨境零售、文旅、餐饮等多业态的系统互联互通,构建更加公平、高效的数字生态。

知识普惠,共促发展:通过开源社区 、技术文档与培训体系,东方仙盟致力于将前沿技术转化为可落地的行业实践,赋能全球合作伙伴,共同培育创新人才,推动数字经济 的普惠式增长

阿雪技术观

在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者 。无论是分享代码、撰写技术博客,还是参与开源项目 维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基 生命,为科技进步添砖加瓦。

Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets , hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology

相关推荐
未来之窗软件服务2 天前
Excel物业台帐租金合同资产—万象EXCEL应用(28) —东方仙盟
excel·仙盟创梦ide·东方仙盟·万象excel
未来之窗软件服务5 天前
计算机考试-C语言 应用题—东方仙盟
c语言·开发语言·仙盟创梦ide·东方仙盟·计算机考试
未来之窗软件服务24 天前
Excel标签批量打印-数千模板——东方仙盟
标签打印·仙盟创梦ide·东方仙盟·excel标签打印
未来之窗软件服务1 个月前
未来之窗昭和仙君(九十五)打印模板与数据处理及打印功能说明书
仙盟创梦ide·东方仙盟·昭和仙君
Splashtop高性能远程控制软件1 个月前
微软2026年6月补丁星期二技术分析:206个漏洞、3个已公开零日的分级修复方案
运维·安全·自动化·远程桌面·splashtop
未来之窗软件服务1 个月前
精选之变,顺势而生(2026 年高考语文作文)
大数据·人工智能·高考·仙盟创梦ide·东方仙盟
未来之窗软件服务1 个月前
2022年软考-疫苗接种系统—软件设计师—东方仙盟
仙盟创梦ide·东方仙盟·计算机考试
未来之窗软件服务1 个月前
自适应开发3分钟重构软件·阿雪心学·无相无界(13)—东方仙盟
重构·架构·仙盟创梦ide·东方仙盟·东方仙盟无相无界
未来之窗软件服务1 个月前
酒店门锁V10SDK接口VB-幽冥大陆(一百26)—东方仙盟
数据库·酒店门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk·东方仙盟幽冥大陆