使用rumqttc+rustls连接自签名证书MQTT broker遇BadSignature错误求助
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Alternative Name: DNS:localhost, DNS:develmqtt.mydomain.com, IP Address:127.0.0.1, IP Address:1.1.1.1 Signature Algorithm: sha256WithRSAEncryption Signature Value: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: ... 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
## 解决办法 ### 1. 检查证书文件完整性 确认加载的CA证书和其他语言环境使用的是同一个文件,没有损坏。可以用`openssl x509 -in your_cert.crt -text -noout`命令校验证书内容,重点核对签名值、公钥段是否完整。 ### 2. 升级依赖版本 rustls旧版本可能对部分签名算法支持不足,尝试升级到最新稳定版,修改`Cargo.toml`: ```toml rustls = "0.21" rumqttc = "0.20" rustls-pemfile = "1.0"
3. 修复证书加载逻辑
当前代码只读取PEM文件中的第一个证书,如果证书链包含中间CA,需要加载所有证书条目:
let mut roots = rustls::RootCertStore::empty(); let file = File::open(cert_path).expect("加载CA证书文件失败"); let mut reader = BufReader::new(file); // 读取所有PEM格式的证书条目 while let Some(item) = rustls_pemfile::read_one(&mut reader).expect("解析证书失败") { if let rustls_pemfile::Item::X509Certificate(cert) = item { roots.add(cert).expect("添加CA证书失败"); } }
4. 临时关闭证书验证(仅测试用)
如果以上方法都无效,可以临时关闭证书验证来确认问题点,但生产环境禁止使用:
use rustls::client::danger::HandshakeSignatureValid; use rustls::client::ServerCertVerified; use rustls::{Certificate, ServerName}; use std::sync::Arc; use std::time::SystemTime; struct NoVerifyCert; impl rustls::client::ServerCertVerifier for NoVerifyCert { fn verify_server_cert( &self, _end_entity: &Certificate, _intermediates: &[Certificate], _server_name: &ServerName, _scts: &mut dyn Iterator<Item = &[u8]>, _ocsp_response: &[u8], _now: SystemTime, ) -> Result<ServerCertVerified, rustls::Error> { Ok(ServerCertVerified::assertion()) } fn verify_tls12_signature( &self, _message: &[u8], _cert: &Certificate, _signature: &[u8], ) -> Result<HandshakeSignatureValid, rustls::Error> { Ok(HandshakeSignatureValid::assertion()) } fn verify_tls13_signature( &self, _message: &[u8], _cert: &Certificate, _signature: &[u8], ) -> Result<HandshakeSignatureValid, rustls::Error> { Ok(HandshakeSignatureValid::assertion()) } fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> { vec![rustls::SignatureScheme::RSA_PKCS1_SHA256] } } // 构建客户端配置时使用自定义验证器 let client_conf = ClientConfig::builder() .with_safe_defaults() .with_custom_certificate_verifier(Arc::new(NoVerifyCert)) .with_no_client_auth();
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

