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

hyper-rustls客户端是否不接受自签名证书?如何跳过证书校验

问题解答

1. 默认校验规则

hyper-rustls 默认会严格执行服务端TLS证书校验。你当前代码中使用了.with_native_roots()配置,该选项只会加载操作系统内置的受信任根证书列表,自签名证书的签发根CA不在这个信任列表中,自然会抛出UnknownIssuer的无效证书错误,这是组件默认的安全设计,不属于异常。

2. 浏览器、curl与客户端表现差异的原因

三者表现不一致完全是信任配置差异导致的:

  • 浏览器可正常访问,是因为你此前已经手动点击过证书风险页的「继续访问」选项,将该自签名站点加入了浏览器的临时信任列表;或是你已经手动将自签名根CA导入了系统/浏览器的受信任根证书存储。
  • curl可正常返回200,要么是你执行命令时携带了-k/--insecure参数主动跳过了证书校验,要么是你已经将自签名根CA导入了系统信任库,curl默认读取系统根证书所以校验通过。
  • 你写的测试客户端没有加载自定义的自签名根CA,也没有关闭校验,所以会直接抛出证书不信任错误。

3. 配置方法

(1)不安全模式:关闭证书校验(仅本地测试使用,禁止生产环境用)

该模式会完全跳过服务端证书有效性校验,存在中间人攻击风险,仅适合本地调试场景。
替换原有的连接器构建代码即可:

use std::sync::Arc;
use rustls::client::{ServerCertVerifier, ServerCertVerified, HandshakeSignatureValid};
use rustls::{Certificate, ServerName, DigitallySignedStruct, Error as RustlsError};

// 实现空校验逻辑,直接返回校验通过
struct NoCheckCertVerifier;
impl ServerCertVerifier for NoCheckCertVerifier {
    fn verify_server_cert(
        &self,
        _end_entity: &Certificate,
        _intermediates: &[Certificate],
        _server_name: &ServerName,
        _scts: &mut dyn Iterator<Item = &[u8]>,
        _ocsp_response: &[u8],
        _now: std::time::SystemTime,
    ) -> Result<ServerCertVerified, RustlsError> {
        Ok(ServerCertVerified::assertion())
    }

    fn verify_tls12_signature(
        &self,
        _message: &[u8],
        _cert: &Certificate,
        _dss: &DigitallySignedStruct,
    ) -> Result<HandshakeSignatureValid, RustlsError> {
        Ok(HandshakeSignatureValid::assertion())
    }

    fn verify_tls13_signature(
        &self,
        _message: &[u8],
        _cert: &Certificate,
        _dss: &DigitallySignedStruct,
    ) -> Result<HandshakeSignatureValid, RustlsError> {
        Ok(HandshakeSignatureValid::assertion())
    }

    fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
        rustls::crypto::ring::default_provider()
            .signature_verification_algorithms
            .supported_schemes()
    }
}

// 构建自定义TLS配置
let tls_conf = rustls::ClientConfig::builder()
    .with_safe_defaults()
    .with_custom_certificate_verifier(Arc::new(NoCheckCertVerifier))
    .with_no_client_auth();

let https = hyper_rustls::HttpsConnectorBuilder::new()
    .with_tls_config(tls_conf)
    .https_only()
    .enable_http1()
    .build();

let client: Client<_, hyper::Body> = Client::builder().build(https);

(2)安全模式:信任自定义自签名根CA(推荐)

不需要关闭证书校验,只需要把你自己签发证书用的根CA加入客户端的信任列表即可,兼顾安全性和可用性:

use std::fs::File;
use std::io::BufReader;
use rustls::RootCertStore;

// 读取本地存储的自签名根CA证书(PEM格式)
let ca_file = File::open("./your-self-signed-root-ca.crt").unwrap();
let mut ca_reader = BufReader::new(ca_file);
let mut root_store = RootCertStore::empty();
for cert in rustls_pemfile::certs(&mut ca_reader).unwrap() {
    root_store.add(&rustls::Certificate(cert)).unwrap();
}

// 构建带自定义根证书的TLS配置
let tls_conf = rustls::ClientConfig::builder()
    .with_safe_defaults()
    .with_root_certificates(root_store)
    .with_no_client_auth();

let https = hyper_rustls::HttpsConnectorBuilder::new()
    .with_tls_config(tls_conf)
    .https_only()
    .enable_http1()
    .build();

let client: Client<_, hyper::Body> = Client::builder().build(https);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:39:20