MQTT客户端启用TLS1.2连接自签名证书服务端被拒绝如何解决
报错根因
你收到的The remote certificate was rejected by the provided RemoteCertificateValidationCallback错误本质是客户端校验服务端TLS证书失败,具体原因有以下几点:
- 你使用的是openssl生成的自签名证书,默认不在操作系统的受信任根证书列表中,系统默认校验逻辑会直接拒绝该证书
- 现有客户端TLS配置仅指定了启用TLS、证书和协议版本,没有配置自定义证书校验回调来适配自签名证书的校验逻辑
- 代码存在两处隐式问题:一是客户端TLS配置中的
certs变量未显式赋值为ConfigCertificate.GetCrtCertificate()的返回值,可能加载证书为空;二是客户端WithTcpServer方法传入的port变量未定义赋值,未匹配服务端监听的8200端口 - 若你生成的服务端证书的使用者名称(CN)或使用者可选名称(SAN)未包含
localhost,也会触发域名匹配校验失败
修复方案
1. 修正客户端TLS配置(推荐方案)
给TLS参数添加自定义证书校验回调,开发环境可以简化校验,生产环境建议严格校验证书指纹避免中间人攻击,修改后的客户端配置代码如下:
// 正确加载要信任的服务端证书 var certs = new List<X509Certificate> { ConfigCertificate.GetCrtCertificate() }; int port = 8200; // 匹配服务端加密端口 var _url = "localhost"; var _topic = "dev.to/topic/json"; var builder = new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString()) .WithTls(new MqttClientOptionsBuilderTlsParameters { UseTls=true, Certificates=certs, SslProtocol=System.Security.Authentication.SslProtocols.Tls12, // 自定义证书校验逻辑 CertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { // 无校验错误直接放行 if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None) return true; // 校验服务端证书指纹和预期一致,替换为你实际生成的证书指纹 var expectedServerCertThumbprint = "你的服务端证书指纹字符串"; return certificate?.GetCertHashString() == expectedServerCertThumbprint; } }) .WithTcpServer(_url, port);
2. 系统级信任证书(无需改代码的方案)
把你生成的自签名根证书导入到客户端设备操作系统的「受信任的根证书颁发机构」存储区,系统默认校验逻辑就会信任该证书,无需修改代码。
3. 双向TLS场景额外配置(按需选择)
如果你的场景需要开启双向TLS认证(服务端也要校验客户端证书合法性),需要在服务端的MqttServerOptionsBuilder配置中追加客户端证书校验逻辑:
var option = new MqttServerOptionsBuilder() .WithEncryptedEndpoint() .WithEncryptedEndpointPort(8200) .WithEncryptionCertificate(ConfigCertificate.GetCertificate().Export(X509ContentType.Pfx)) .WithEncryptionSslProtocol(System.Security.Authentication.SslProtocols.Tls12) // 新增双向TLS校验配置 .WithClientCertificate() .WithClientCertificateValidationCallback(context => { // 校验客户端证书指纹是否和预期一致 var expectedClientCertThumbprint = ConfigCertificate.GetCrtCertificate().GetCertHashString(); return context.Certificate?.GetCertHashString() == expectedClientCertThumbprint; }) .WithConnectionValidator(OnNewConnection) .WithApplicationMessageInterceptor(OnNewMessage);
4. 证书生成校验
生成服务端证书时要确保在openssl配置中指定了使用者可选名称(SAN)包含localhost,避免域名匹配失败。
内容的提问来源于stack exchange,提问作者behroozbc
相关产品推荐
相关产品推荐

