使用 M2MQTT v4.3.0.0 和签名证书建立与 Mosquitto Broker 2.0.10 的安全连接的问题

Issues establishing a secure connection to Mosquitto Broker 2.0.10 using M2MQTT v4.3.0.0 and signed certificates

我正在尝试使用 M2MQTT v4.3.0.0 (github) 在我的程序中实现 MQTT,但是当我尝试使用签名证书进行连接时,我的代码无法建立连接。我在 Windows 10 系统上,使用 C# 和 .NET 4.8。我安装的Mosquitto版本是2.0.10.

为了制作服务器证书,我遵循了本教程: http://www.steves-internet-guide.com/mosquitto-tls/#server

为了制作客户端证书,我遵循了本教程: http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/

我还在 etc/hosts 文件中为 127.0.0.1 创建了一个指向 的主机名]localhost.conrad.com.

我的 Mosquitto Broker 的配置是:

bind_address localhost.conrad.com
port 8883
allow_anonymous true
cafile C:/mosquitto/certs/ca.crt
keyfile C:/mosquitto/certs/server.key
certfile C:/mosquitto/certs/server.crt
require_certificate true
tls_version tlsv1.2
log_dest file C:/mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information

我使用 Mosquitto 的命令行发布工具

成功测试了此配置是否有效
mosquitto_pub --cafile C:\mosquitto\certs\ca.crt --cert C:\mosquitto\certs\client.crt --key C:\mosquitto\certs\client.key -d -h localhost.conrad.com -p 8883 -t herp/derp/test -m "hi"

我在使用命令后收到此消息。

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'herp/derp/test', ... (2 bytes))
Client (null) sending DISCONNECT

我的 Mosquitto 日志确认连接成功:

1621547553: New connection from 127.0.0.1:57874 on port 8883.
1621547553: New client connected from 127.0.0.1:57874 as auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 (p2, c1, k60).
1621547553: Client auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 disconnected.

但是,当我尝试使用 M2MQTT 进行连接时,我 运行 在尝试使用签名证书进行连接时遇到了问题。我的代码如下:

int securePort = 8883;
MqttClient client = null;
string subTopic1 = "herp/derp/test";
string subTopic2 = "herp/derp/test2";
X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");
string clientID = "TestClientID";

public MQTTTest()
{
    try
    {
        client = new MqttClient("localhost.conrad.com", securePort, true, caCert, clientCert, MqttSslProtocols.TLSv1_2, RemoteCertificateValidationCallback);
        client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
        client.MqttMsgPublished += client_MqttMsgPublished;
        client.MqttMsgSubscribed += client_MqttMsgSubscribed;
        client.ConnectionClosed += client_ConnectionClosed;

        client.Connect(clientID, "", "", true, 1000);
        client.Subscribe(new string[] { subTopic1, subTopic2 }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

尝试 client.Connect.

时出现以下异常
Exception message: "A call to SSPI failed, see inner exception."
Inner exception: "The message received was unexpected or badly formatted"

我的 Mosquitto 日志显示:

1621547793: New connection from 127.0.0.1:57896 on port 8883.
1621547793: OpenSSL Error[0]: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
1621547793: Client <unknown> disconnected: protocol error.

我可以很好地建立不安全的连接。当我在我的 Mosquitto 配置文件中将 require_certificate 设置为 false 时,我的代码也会连接;但是我担心如果 require_certificate 设置为 false 我将无法获得我想要的安全性。任何帮助将不胜感激。

多亏了 Brits 的评论,我才弄明白了 ()。我制作了一个 pfx 证书并使用它而不是使用 crt。

而不是...

X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");

我用过...

X509Certificate2 caCert = new X509Certificate2("C:/mosquitto/certs/ca.pfx", "password");
X509Certificate2 clientCert = new X509Certificate2("C:/mosquitto/certs/client.pfx", "password");