MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

Using Client Certificates / Console Example

Open johnjore opened this issue 6 years ago • 0 comments

Describe your question

As a few others, I had a lot of issues getting client certificates to work (using mosquitto on server side). Attached is a (poorly written) console example that worked for me. Hopefully this helps someone.

Which project is your question related to?

  • Client
using System;
using System.Collections.Generic;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Formatter;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Security.Authentication;
using System.IO;

namespace MQTT
{
    class Program
    {
        const string strMQTTTopic = "owntracks/someone/something";
        const string strMQTTTrackerID = "Tracker";
        const string strMQTTUser = "User";
        const string strMQTTPassword = "Password";
        const int intMQTTPort = 1234;
        const string strMQTTServer = "1.1.1.2";
        const string clientId = "ClientID";
        const string currentPath = @"C:\APath\";
        const string rootCertName = "RootCert.crt";
        const string userCertName = "PasswordProtected.pfx";
        const string CertPriveKey = "ThePassword";
        
        static void Main(string[] args)
        {
            _ = PubMQTTAsync();
            Console.ReadLine();
        }

        static async System.Threading.Tasks.Task PubMQTTAsync()
        {
            var mqttClient = new MqttFactory().CreateMqttClient();
            string pubTopic = strMQTTTopic.ToLower();
            string pubMessage = "{\"_type\":\"location\",\"batt\":\"30\",\"tid\":\"" + strMQTTTrackerID + "\",\"lat\":10.000,\"lon\":-0.0000,\"t\":\"t\",\"tst\":" + ConvertToUnixTimestamp(DateTime.Now).ToString() + "}";
            Console.WriteLine("Pub Topic: '" + pubTopic + "'");
            Console.WriteLine("Pub Message: '" + pubMessage + "'");

            try
            {
                X509Certificate rootCert = X509Certificate.CreateFromSignedFile(Path.Combine(currentPath, rootCertName));
                X509Certificate2 certificate = new X509Certificate2(Path.Combine(currentPath, userCertName), CertPriveKey);
                Console.WriteLine("Has Private Key: '" + certificate.HasPrivateKey.ToString() + "'");

                var TLSParameters = new MqttClientOptionsBuilderTlsParameters
                {
                    UseTls = true,
                    IgnoreCertificateChainErrors = false,
                    IgnoreCertificateRevocationErrors = false,
                    AllowUntrustedCertificates = false,
                    SslProtocol = SslProtocols.Tls12,
                    CertificateValidationCallback = (X509Certificate x, X509Chain y, SslPolicyErrors z, IMqttClientOptions o) =>
                    {
                        return true;
                    },
                    Certificates = new List<byte[]> {
                        new X509Certificate2(certificate).Export(X509ContentType.Cert),
                        new X509Certificate(rootCert).Export(X509ContentType.Cert),
                    },
                };

                var options = new MqttClientOptionsBuilder()
                    .WithClientId(clientId)
                    .WithTcpServer(strMQTTServer, intMQTTPort)
                    .WithCredentials(strMQTTUser, strMQTTPassword)
                    .WithCleanSession()
                    .WithTls(TLSParameters)
                    .WithProtocolVersion(MqttProtocolVersion.V311)
                    .Build();

                await mqttClient.ConnectAsync(options);

                var message = new MqttApplicationMessageBuilder()
                    .WithTopic(pubTopic)
                    .WithPayload(pubMessage)
                    .WithExactlyOnceQoS()
                    .WithRetainFlag()
                    .Build();
                await mqttClient.PublishAsync(message);
                Console.WriteLine("Published!!!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to send, Exception: " + ex.ToString());
            }
        }

        private static double ConvertToUnixTimestamp(DateTime date)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan diff = date.ToUniversalTime() - origin;
            return System.Math.Floor(diff.TotalSeconds);
        }
    }
}

johnjore avatar Mar 24 '20 11:03 johnjore