MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

Client Certificates approach with MQTTnet server and .NET 5

Open itsoli91 opened this issue 3 years ago • 2 comments

Hi, I'm trying to implement Client Certificates approach with MQTTnet server and .NET 5

I have created ca.crt andclient.crtfiles 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

Screenshot 2021-09-06 185303

Does MQTTNet Server supports Client Certificates? if yes, then what part of my code is wrong ?

itsoli91 avatar Sep 06 '21 14:09 itsoli91

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))

Yussef77 avatar Sep 06 '21 19:09 Yussef77

I think because this issue https://github.com/chkr1011/MQTTnet/issues/464 you cant use tls asp.net 5

behroozbc avatar Nov 01 '21 20:11 behroozbc

I assume this question is answered.

chkr1011 avatar Nov 11 '22 07:11 chkr1011