MQTTnet
MQTTnet copied to clipboard
Can't connect to a MQTT Server with supplied certificates
Hi there, I am sorry if this is the wrong place to ask this, but I have been trying for the last weeks to connect to a MQTT Server for an application I am working on.
From this Server I got 3 files used as certificates:
- ca.pem
- mqtt.pem
- mqtt.key Both pem files start with -----BEGIN CERTIFICATE----- The .key file starts with -----BEGIN RSA PRIVATE KEY-----
My issue is that I can't seem to figure out how to connect to the Server with those certificates.
I did get an example from the Devs that made the Server, but it is in JavaScript:
var fs = require('fs');
const mqtt = require('mqtt')
console.log('mqtt test started...');
var KEY = fs.readFileSync('./cert/mqtt.key')
var CERT = fs.readFileSync('./cert/mqtt.pem')
var TRUSTED_CA_LIST = fs.readFileSync('./cert/ca.pem')
var PORT = 1883; // mqtt port
var HOST = '127.0.0.1'; // mqtt server
var options = {
port: PORT,
host: HOST,
key: KEY,
cert: CERT,
rejectUnauthorized: false,
ca: TRUSTED_CA_LIST,
protocol: 'mqtts'
}
console.log('try to connect....');
const client = mqtt.connect(options)
The example I got works perfectly, but since my project is in C# I can't use the one they provided.
Am I just getting stuck with a somewhat simple issue or is this something else?
I'd love to know how I should use those files in MQTTnet since everything I tried leads me to the error
The remote certificate was rejected
and I even tried the mqttMultimeter, but I get the same error.
I even tried to convert the mqtt.pem and the mqtt.key to a .pfx file with openssl, but it still gets rejected.
Which project is your question related to?
- Client
MQTTnet uses the Windows plumbing to handle TLS. Did you add at least the CA certificate to the the machine’s certificate store?
On Wed, Oct 25, 2023, at 05:34, MVSAlex wrote:
Hi there, I am sorry if this is the wrong place to ask this, but I have been trying for the last weeks to connect to a MQTT Server for an application I am working on.
From this Server I got 3 files used as certificates:
• ca.pem • mqtt.pem • mqtt.key Both pem files start with -----BEGIN CERTIFICATE----- The .key file starts with -----BEGIN RSA PRIVATE KEY----- My issue is that I can't seem to figure out how to connect to the Server with those certificates.
I did get an example from the Devs that made the Server, but it is in JavaScript:
`var fs = require('fs'); const mqtt = require('mqtt')
console.log('mqtt test started...');
var KEY = fs.readFileSync('./cert/mqtt.key') var CERT = fs.readFileSync('./cert/mqtt.pem') var TRUSTED_CA_LIST = fs.readFileSync('./cert/ca.pem')
var PORT = 1883; // mqtt port var HOST = '127.0.0.1'; // mqtt server
var options = { port: PORT, host: HOST, key: KEY, cert: CERT, rejectUnauthorized: false, ca: TRUSTED_CA_LIST, protocol: 'mqtts' }
console.log('try to connect....');
const client = mqtt.connect(options) ` The example I got works perfectly, but since my project is in C# I can't use the one they provided.
Am I just getting stuck with a somewhat simple issue or is this something else? I'd love to know how I should use those files in MQTTnet since everything I tried leads me to the error
The remote certificate was rejected
and I even tried the mqttMultimeter, but I get the same error. I even tried to convert the mqtt.pem and the mqtt.key to a .pfx file with openssl, but it still gets rejected.Which project is your question related to?
• Client
— Reply to this email directly, view it on GitHub https://github.com/dotnet/MQTTnet/issues/1863, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7NHNIOZWPWMZJCSJCTYBDMJDAVCNFSM6AAAAAA6PBX4FKVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE3DAOJWGI2TGOI. You are receiving this because you are subscribed to this thread.Message ID: @.***>
Yeah I did try to add both .pem certificates to the local machine certificate store and to the current user certificate store which both locations changed nothing. I also tried to import pfx file I created and it said it was imported, but it didn't change anything either.
var mqttFactory = new MqttFactory();
using (var mqttClient = mqttFactory.CreateMqttClient())
{
// Use builder classes where possible in this project.
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("192.168.0.30", 1883).WithTlsOptions(o =>
{
o.UseTls(true);
o.WithAllowUntrustedCertificates(true);
o.WithClientCertificates(new List<X509Certificate2>
{
new X509Certificate2(File.ReadAllBytes("cert\\mqtt.pem"))
});
o.Build();
}).Build();
try
{
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
// Send a clean disconnect to the server by calling _DisconnectAsync_. Without this the TCP connection
// gets dropped and the server will handle this as a non clean disconnect (see MQTT spec for details).
var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}
This is the code I currently have and adding more than one certificate to the list doesn't change anything or causes the code to just stop right at the WithClientCertificates
line without any errors.
I tried multiple configurations, but apparently not the right one
What’s the exception(s) you’re getting?
On Wed, Oct 25, 2023, at 08:22, MVSAlex wrote:
Yeah I did try to add both .pem certificates to the local machine certificate store and to the current user certificate store which both locations changed nothing. I also tried to import pfx file I created and it said it was imported, but it doesn't show up in the certificate store.
`var mqttFactory = new MqttFactory();
using (var mqttClient = mqttFactory.CreateMqttClient()) { // Use builder classes where possible in this project. var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("192.168.0.30", 1883).WithTlsOptions(o => { o.UseTls(true); o.WithAllowUntrustedCertificates(true); o.WithClientCertificates(new List<X509Certificate2> { new X509Certificate2(File.ReadAllBytes("cert\mqtt.pem")) }); o.Build(); }).Build();
try { var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
} catch (Exception ex) { Console.WriteLine(ex); }
// Send a clean disconnect to the server by calling DisconnectAsync. Without this the TCP connection // gets dropped and the server will handle this as a non clean disconnect (see MQTT spec for details). var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None); } `
This is the code I currently have and adding more than one certificate to the list causes the code to just stop right at the
WithClientCertificates
line without any errors. I tried multiple configurations, but apparently not the right one— Reply to this email directly, view it on GitHub https://github.com/dotnet/MQTTnet/issues/1863#issuecomment-1779155003, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7JYNWW2657VHQ4DJATYBEAARAVCNFSM6AAAAAA6PBX4FKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZZGE2TKMBQGM. You are receiving this because you commented.Message ID: @.***>
Oh yeah right. Sorry about that. Also my error message is in german so I translated it
MQTTnet.Exceptions.MqttCommunicationException: The remote certificate is invalid according to the validation procedure. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at MQTTnet.Implementations.MqttTcpChannel.<ConnectAsync>d__17.MoveNext()
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MQTTnet.Adapter.MqttChannelAdapter.<ConnectAsync>d__34.MoveNext()
--- End of internal exception stack trace ---
at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception)
at MQTTnet.Adapter.MqttChannelAdapter.<ConnectAsync>d__34.MoveNext()
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MQTTnet.Client.MqttClient.<ConnectInternal>d__53.MoveNext()
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at MQTTnet.Client.MqttClient.<ConnectAsync>d__41.MoveNext()
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at MQTTnet.Client.MqttClient.<ConnectAsync>d__41.MoveNext()
--- End of stack trace from previous location where the exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MVSXesarIntegration.MQTTClient.<Connect>d__0.MoveNext() in C:\_devA\MQTTTest\MQTTTest\MQTTClient.cs: Line 55.
If I run the MQTTMultimeter to the same Server I get a similar error:
MQTTnet.Exceptions.MqttCommunicationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
---> System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken)
at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken)
at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception)
at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectInternal(CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
at mqttMultimeter.Services.Mqtt.MqttClientService.Connect(ConnectionItemViewModel item)
at mqttMultimeter.Pages.Connection.ConnectionPageViewModel.Connect(ConnectionItemViewModel item)
This issue https://github.com/dotnet/MQTTnet/issues/1857 address the same scenario.
In the meantime, you can configure MqttNet like in this sample
https://github.com/Azure-Samples/MqttApplicationSamples/blob/main/mqttclients/dotnet/MQTTnet.Client.Extensions/WithTlsSettings.cs
Thank you for the Sample. I sadly can't try it out right now, but I am sure this will work and it looks promising.