在我的 MQTT 代理中,当活动 TLS 1.2 客户端无法连接到代理并获得此异常时
远程证书被提供的 RemoteCertificateValidationCallback 拒绝
注意:我使用由 openssl 生成的自签名证书。
经纪人代码
using MQTTnet.Server;
using System;
using MQTTnet;
using System.Text;
using static System.Console;
using System.Threading;
using System.Security.Cryptography.X509Certificates;
using SharedItems;
var wait = new ManualResetEvent(false);
var option = new MqttServerOptionsBuilder()
.WithEncryptedEndpoint()
.WithEncryptedEndpointPort(8200)
.WithEncryptionCertificate(ConfigCertificate.GetCertificate().Export(X509ContentType.Pfx))
.WithEncryptionSslProtocol(System.Security.Authentication.SslProtocols.Tls12)
.WithConnectionValidator(OnNewConnection)
.WithApplicationMessageInterceptor(OnNewMessage);
var mqttServer = new MqttFactory().CreateMqttServer();
await mqttServer.StartAsync(option.Build());
wait.WaitOne();
static void OnNewConnection(MqttConnectionValidatorContext context)
{
WriteLine(
"New connection: ClientId = {0}, Endpoint = {1}",
context.ClientId,
context.Endpoint);
}
static void OnNewMessage(MqttApplicationMessageInterceptorContext context)
{
var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload);
WriteLine(
" TimeStamp: {0} -- Message: ClientId = {1}, Topic = {2}, Payload = {3}, QoS = {4}, Retain-Flag = {5}",
DateTime.Now,
context.ClientId,
context.ApplicationMessage?.Topic,
payload,
context.ApplicationMessage?.QualityOfServiceLevel,
context.ApplicationMessage?.Retain);
}
ConfigCertificate.GetCertificate
方法代码(没关系并返回证书)
public static X509Certificate2 GetCertificate()
{
var currectPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var certificationPath = Path.Combine(currectPath, "Assets/key/mycert.pfx");
return new X509Certificate2(certificationPath, "password", X509KeyStorageFlags.Exportable);
}
mqtt 客户端代码
using System;
using MQTTnet;
using System.Text;
using static System.Console;
using MQTTnet.Client.Options;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Extensions.ManagedClient;
using System.Text.Json;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using SharedItems;
WriteLine("Start App");
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
})
.WithTcpServer(_url, port);
var option = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(50)).WithClientOptions(builder.Build()).Build();
var client = new MqttFactory().CreateManagedMqttClient();
client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected);
client.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(OnConnectingFailed);
client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnDisconnected);
client.StartAsync(option).GetAwaiter().GetResult();
client.UseApplicationMessageReceivedHandler(context =>
{
var payload = context.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload);
WriteLine(
" TimeStamp: {0} -- Message: ClientId = {1}, Topic = {2}, Payload = {3}, QoS = {4}, Retain-Flag = {5}",
DateTime.Now,
context.ClientId,
context.ApplicationMessage?.Topic,
payload,
context.ApplicationMessage?.QualityOfServiceLevel,
context.ApplicationMessage?.Retain);
});
while (true)
{
if (!client.IsConnected)
continue;
string json = JsonSerializer.Serialize(new {id=Guid.NewGuid(), message = "Heyo :)", sent = DateTimeOffset.UtcNow });
await client.PublishAsync(_topic, json);
WriteLine("Send Data");
await Task.Delay(1000);
}
static void OnConnected(MqttClientConnectedEventArgs obj)
{
WriteLine("Successfully connected.");
}
static void OnConnectingFailed(ManagedProcessFailedEventArgs obj)
{
WriteLine("Couldn't connect to broker."+obj.Exception.Message);
}
static void OnDisconnected(MqttClientDisconnectedEventArgs obj)
{
WriteLine("Successfully disconnected. "+ obj.Exception.Message);
}
ConfigCertificate.GetCrtCertificate
(没关系并返回证书):
public static X509Certificate GetCrtCertificate()
{
var currectPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var certificationPath = Path.Combine(currectPath, "Assets/key/client.crt");
return X509Certificate.CreateFromCertFile(certificationPath);
}
为什么客户端会收到此错误?修复和客户端如何连接到代理?