1

I hope, that you can help me here. I'm trying to make a MQTT client (azure function in an app service environment) that extracts data from MQTT broker (hivemq), but I'm kind of lost when it comes to certificates (I'm not an expert).

Anyways, I received 3 files (look below) from our partner (that's them with the MQTT broker), but the question is. How should I use these PEM files in the application??

  • Client certificate == mqtt-client-cert.pem
  • Client key == mqtt-client-key_nopass.pem
  • CA certificate == server.pem

Here is the application and here is an example where I tested it locally (with a crt certificate) against an test broker (test.mosquitto.org). It worked perfectly, but now I just need to the same thing, just with 3 PEM files instead.

I also suspect that I need to do something on Azure (either on function app or app service environment level) in order to use these certificates?

            // Create a new MQTT client.
            var factory = new MqttFactory();
            var mqttClient = factory.CreateMqttClient();

            // Load certificate 
            X509Certificate caCertificate = new X509Certificate(@"..\mosquitto.org.crt");

            // Create TLS based parameters.
            var tlsParameters = new MqttClientOptionsBuilderTlsParameters
            {
                UseTls = true,
                Certificates = new List<X509Certificate> { caCertificate },
                SslProtocol = System.Security.Authentication.SslProtocols.Tls12
            };

            // Create TCP based options using the builder.
            var connectOptions = new MqttClientOptionsBuilder() 
                .WithTcpServer("test.mosquitto.org", 8883)
                .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311)
                .WithTls(tlsParameters)
                .Build();

            var conResult = await mqttClient.ConnectAsync(connectOptions);
                              
            mqttClient.UseConnectedHandler(e =>
            {
                Console.Write("Connected successfully with MQTT Brokers.");
            });
            mqttClient.UseDisconnectedHandler(e =>
            {
                Console.Write("Disconnected from MQTT Brokers.");
            });
Zaz
  • 1,074
  • 3
  • 17
  • 29

1 Answers1

1

.crt files normally contain PEM encoded keys/certs so in this case the file extension doesn't make any difference.

You should be able to replace the mosquitto.org.crt with the server.pem.

The other 2 files are for what is known as mutual TLS authentication. For most TLS connections (e.g. when making a HTTPS request for a web page) only one side of the connection needs a certificate/private key. This is the server. The client uses a collections of CA certificates to validate that the service is what it claims to be. (This is what you are doing using the mosquitto.org.crt file).

In other cases we want to authenticate both ends of the connection (the client wants to know what the server is and the server wants to know who the client is). To do this the client need to also present a certificate to the server, this is what the other 2 files are for.

The MQTTNet documentation includes an example of setting up a connection using client certificates here but that uses a .pfx (a pfx is just another name for a PKCS12 container, if needed you can convert the .pem files into a .pfx/.p12 file using openssl e.g. openssl pkcs12 -export -out mqtt-client.p12 -inkey mqtt-client-key_nopass.pem -in mqtt-client-cert.pem -CAfile server.pem)

List<X509Certificate> certs = new List<X509Certificate>
{
    new X509Certificate2("myCert.pfx")
};

var options = new MqttClientOptionBuilder()
    .WithTcpServer(broker, port)
    .WithTls(new MqttClientOptionsBuilderTlsParameters
    {
        UseTls = true,
        Certificates = certs
    })
    .Build();
hardillb
  • 54,545
  • 11
  • 67
  • 105
  • Hi hardillb, Thank you for your help. That helped me a lot and gave me a deeper understanding. Now I'm trying to convert the .pem files into a pfx/.p12 file as you stated in your example, but here I'm getting the error: unrecognized flag CAFile? – Zaz Dec 25 '20 at 22:17
  • @Zaz sorry, there was a typo, it should be `-CAfile`. I've updated the answer – hardillb Dec 25 '20 at 22:23
  • Hi @hardillb, thank you for your help and sorry for the late response. Due to corona, we have been shut down but now we are back in-game again. – Zaz Mar 01 '21 at 13:04
  • Maybe I should have been more clear. The Azure Function is a time trigger and triggers every 5 second in order to get new content from the server. Do you still think I should use mutual TLS authentication? I have followed your example and converted the files into a .pfx/.p12 file using openssl e.g. openssl pkcs12 -export -out mqtt-client.p12 -inkey mqtt-client-key_nopass.pem -in mqtt-client-cert.pem -CAfile server.pem but here I'm getting an exception: "The credentials supplied to the package were not recognized"??? – Zaz Mar 01 '21 at 13:04