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

如何用mysql_async创建MariaDB TLS连接?证书配置故障排查

Rust连接MariaDB 10.x的SSL证书配置问题

我用Rust连接MariaDB 10.x数据库,持有客户端证书、CA证书、客户端密钥三个文件,但始终无法建立连接。尝试了rustls-tls和native-tls两种TLS后端,各种SSL配置组合均失败,错误信息如下:

使用rustls-tls时的错误

called `Result::unwrap()` on an `Err` value: Io(Io(Custom { kind: InvalidData, error: InvalidCertificate(Other(UnsupportedCertVersion)) }))
called `Result::unwrap()` on an `Err` value: Io(Tls(Tls(InvalidCertificate(BadEncoding))))

使用native-tls时的错误

called `Result::unwrap()` on an `Err` value: Io(Tls(TlsError(Os { code: -2146893018, kind: Uncategorized, message: "The format of the received message was unexpected or incorrect." })))
called `Result::unwrap()` on an `Err` value: Io(Tls(TlsError(Os { code: -2146881269, kind: Uncategorized, message: "ASN1 Invalid license plate value." })))

尝试过的SSL配置组合

let ssl_opts = SslOpts::default()
    .with_danger_accept_invalid_certs(true)
    .with_client_identity(Some(ClientIdentity::new(
        Path::new("/src/ssl2/client-cert.pem"),
        Path::new("/src/ssl2/client-key.pem"),
    )))
    .with_client_identity(Some(ClientIdentity::new(
        Path::new("/src/ssl2/ca-cert.pem"),
        Path::new("/src/ssl2/ca-key.pem"),
    )))
    .with_client_identity(Some(ClientIdentity::new(
        Path::new("/src/ssl2/server-cert.pem"),
        Path::new("/src/ssl2/server-key.pem"),
    )));

let ssl_opts = SslOpts::default()
    .with_danger_accept_invalid_certs(true)
    .with_client_identity(Some(
        ClientIdentity::new(Path::new("/src/ssl2/client-identity.p12"))
            .with_password("Password"),
    ))
    .with_root_cert_path(Some(Path::new("/src/ssl2/client-cert.pem")))
    .with_root_cert_path(Some(Path::new("/src/ssl2/client-key.pem")))
    .with_root_cert_path(Some(Path::new("/src/ssl2/ca-cert.pem")))
    .with_root_cert_path(Some(Path::new("/src/ssl2/ca-key.pem")));

let ssl_opts = SslOpts::default()
    .with_danger_accept_invalid_certs(true)
    .with_client_identity(Some(
        ClientIdentity::new(Path::new("/src/ssl2/client-identity.p12"))
            .with_password("Password"),
    ));

这些证书可正常用于MySQL Workbench和HeidiSQL,请问证书使用环节存在什么问题?


问题分析与解决思路

1. 核心配置错误

你之前的配置存在几个关键逻辑错误:

  • 重复调用with_client_identity:该方法是覆盖式设置,多次调用后仅最后一次配置生效,导致客户端身份被错误设置为server证书/密钥,完全不符合TLS身份验证逻辑。
  • 混淆根证书与客户端证书:with_root_cert_path仅需传入CA证书,你把客户端证书、密钥都传入,TLS后端会将这些非CA证书当作可信根证书解析,必然出现编码或格式错误。
  • P12与PEM配置冗余:若已使用P12文件作为客户端身份,无需额外指定PEM格式的证书/密钥,冗余配置会干扰解析流程。

2. 正确配置示例

方式一:使用PEM格式证书(客户端证书+密钥+CA证书)

use std::path::Path;
use mysql_async::SslOpts;

let ssl_opts = SslOpts::default()
    // 仅测试用,生产环境禁止开启
    .with_danger_accept_invalid_certs(true)
    // 设置客户端身份:客户端证书+客户端密钥
    .with_client_identity(Some(mysql_async::ClientIdentity::new(
        Path::new("/src/ssl2/client-cert.pem"),
        Path::new("/src/ssl2/client-key.pem"),
    )))
    // 设置可信根证书:仅传入CA证书
    .with_root_cert_path(Some(Path::new("/src/ssl2/ca-cert.pem")));

方式二:使用P12格式客户端身份文件

确保P12文件包含客户端证书、密钥,若未内置CA证书则需单独指定:

use std::path::Path;
use mysql_async::SslOpts;

let ssl_opts = SslOpts::default()
    .with_danger_accept_invalid_certs(true)
    .with_client_identity(Some(
        mysql_async::ClientIdentity::new(Path::new("/src/ssl2/client-identity.p12"))
            .with_password("Password"),
    ))
    // 若P12未包含CA证书,需单独指定
    .with_root_cert_path(Some(Path::new("/src/ssl2/ca-cert.pem")));

3. 证书格式排查

  • 检查客户端密钥是否为未加密的PEM格式,rustls对加密密钥支持有限,若为加密密钥需先解密。
  • 确认CA证书是标准PEM格式,无多余空白行或格式损坏。
  • 针对rustls的UnsupportedCertVersion错误:检查证书版本是否为X.509 v3,rustls不支持v1/v2版本证书,而MySQL Workbench可能兼容旧版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:43:09