对 SSPI 的调用失败,请参阅内部异常 paho m2mqtt Dot.Net(c#) 客户端 SSL/TLS 连接

A call to SSPI failed, see inner exception paho m2mqtt Dot.Net(c#) client SSL/TLS connection

我正在尝试通过 SSL/TLS 使用 m2mqtt c# 客户端版本 4.3.0 库与 mosquitto 代理连接。下面是我试过的代码

static void Main(string[] args)
    {

        // create client instance
        MqttClient client = new MqttClient(IPAddress.Parse("127.0.0.1"), 8883, true, 
                                new X509Certificate2("C:\Users\hp\Desktop\certificate\ca.crt"), 
                                new X509Certificate2("C:\Users\hp\Desktop\certificate\client.crt"), 
                                MqttSslProtocols.TLSv1_2);

        // register to message received
        client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

        string clientId = "pahoSubscriber2";
        client.Connect(clientId);

        // subscribe to the topic "hello" with QoS 0
        client.Subscribe(new string[] { "hello" }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });

    }

static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
    {
        // handle message received
        Console.WriteLine(e.Message);
    }

但我遇到了异常

A call to SSPI failed, see inner exception.

内部异常显示

the message received was unexpected or badly formatted

有关信息,我可以在没有 SSL/TLS 的情况下成功连接到代理。也可以通过有或没有 SSL/TLS 使用 Paho Java 客户端,我可以与经纪人联系。仅当我尝试通过 SSL/TLS 使用 m2mqtt C# 客户端库进行连接时才会发生此异常。将提供任何帮助或示例实施。

终于找到解决办法了。要在 Dot.Net 框架内使用 SSL 证书,我们需要同时提供证书及其对应的私钥。为此,我们需要使用结合了这两者的 p12(.pfx) 文件。在我的项目中,我使用了使用 OpenSSL 的自签名证书,所以我使用下面的命令来组合证书和私钥

pkcs12 -export -out ca.pfx -inkey ca.key -in ca.crt
pkcs12 -export -out client.pfx -inkey client.key -in client.crt

这将为每个证书创建 p12(.pfx) 文件。然后我将它们用到我的代码中,如下所示

static void Main(string[] args)
    {

        // create client instance
        MqttClient client = new MqttClient(IPAddress.Parse("127.0.0.1"), 8883, true, 
                                new X509Certificate2("C:\Users\hp\Desktop\certificate\ca.pfx"), 
                                new X509Certificate2("C:\Users\hp\Desktop\certificate\client.pfx"), 
                                MqttSslProtocols.TLSv1_2);

        // register to message received
        client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

        string clientId = "pahoSubscriber2";
        client.Connect(clientId);

        // subscribe to the topic "hello" with QoS 0
        client.Subscribe(new string[] { "hello" }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });

    }

static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
    {
        // handle message received
        Console.WriteLine(e.Message);
    }

因为我遇到的关键点是在本地机器上安装证书作为根证书!如果安装了 'ca.crt' 文件,您可以为两个参数使用 null 值 => caCert 和 clientCert。 这 link 在我困惑了几个小时后帮助了我!

 static void Main(string[] args){
// create client instance
MqttClient client = new MqttClient(IPAddress.Parse("127.0.0.1"), 8883,   true, null, null, MqttSslProtocols.TLSv1_2);

    // register to message received
    client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

    string clientId = "pahoSubscriber2";
    client.Connect(clientId);

    // subscribe to the topic "hello" with QoS 0
    client.Subscribe(new string[] { "hello" }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });

}

static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
    // handle message received
    Console.WriteLine(e.Message);
}