MQTTnet
MQTTnet copied to clipboard
Client Certificates approach with MQTTnet server and .NET 5
Hi, I'm trying to implement Client Certificates approach with MQTTnet server and .NET 5
I have created ca.crt
andclient.crt
files using below commands
openssl genrsa -des3 -out ca.key 2048
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
openssl genrsa -out client.key 2048
openssl req -new -out client.csr -key client.key
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 360
So I have ca.key, ca.crt, client.key, client.csr, client.crt, ca.srl
files ready.
Below is my codes for ASP.NET Core Using .NET 5
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(
o =>
{
o.ListenAnyIP(1883, l => { l.UseMqtt(); }); // MQTT pipeline
o.ListenAnyIP(80); // Default HTTP pipeline
});
webBuilder.UseStartup<Startup>();
});
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (currentPath == null)
throw new ArgumentNullException(nameof(currentPath), "Path to certificate was not found");
var certificate = new X509Certificate2(Path.Combine(currentPath, "ca.crt"), "mypassword", X509KeyStorageFlags.Exportable);
services
.AddHostedMqttServer(mqttServer =>
{
mqttServer
.WithoutDefaultEndpoint(); // This call disables the default unencrypted endpoint on port 1883
mqttServer.WithEncryptedEndpoint();
mqttServer.WithEncryptedEndpointPort(1883);
mqttServer.WithEncryptionCertificate(certificate.Export(X509ContentType.Cert));
mqttServer.WithEncryptionSslProtocol(SslProtocols.Tls12);
mqttServer.WithConnectionValidator(new MqttConnectionValidatorService());
})
.AddMqttConnectionHandler()
.AddConnections();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapConnectionHandler<MqttConnectionHandler>(
"/mqtt",
httpConnectionDispatcherOptions => httpConnectionDispatcherOptions.WebSockets.SubProtocolSelector =
protocolList =>
protocolList.FirstOrDefault() ?? string.Empty);
});
app.UseMqttServer(server =>
{
server.ApplicationMessageReceivedHandler =
new MqttApplicationMessageHandler();
});
}
}
However, when I try to connect to Server using MQTT Clients like MQTTX, it can not connect Below is an image of my configuration in MQTTX client application
Does MQTTNet Server supports Client Certificates? if yes, then what part of my code is wrong ?
I think the problem is in ca.crt.
I have a certificate with a pfx extension. And when putting the client certificates, generated with the code that you indicate, I have no problem.
On the other hand, if I occupy the generated ca.crt with its code, I don't get a connection either.
So I created the pfx:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
openssl pkcs12 -export -out certificate.pfx -inkey key.pem -in cert.pem
Also, you have to change:
.WithEncryptionCertificate(certificate.Export(X509ContentType.Pfx))
I think because this issue https://github.com/chkr1011/MQTTnet/issues/464 you cant use tls asp.net 5
I assume this question is answered.