如何在 MQTTnet 中使用客户端证书和密钥?

发布于 2025-01-19 13:47:50 字数 1357 浏览 4 评论 0原文

我想用MQTTNET复制此Python代码样本。

client = mqtt.Client(str(uuid4()))
current = dirname(__file__)
cerfile = join(current, "rcm_certchain_pem.cer")
keyfile = join(current, "rcm_pem_privkey.pkcs8")
context = create_default_context(Purpose.CLIENT_AUTH)
context.load_cert_chain(cerfile, keyfile)
client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect("192.168.1.X", 1234)

我尝试了mqttnet。

var manager = new MqttFactory().CreateMqttClient();
var options = new MqttClientOptionsBuilder()
    .WithCleanSession()
    .WithClientId(Guid.NewGuid().ToString())
    .WithTcpServer(address, port)
    .WithTls(new MqttClientOptionsBuilderTlsParameters()
    {
        AllowUntrustedCertificates = true,
        Certificates = new List<X509Certificate>
        {
            new X509Certificate2("Assets/rcm_certchain_pem.cer"),
            new X509Certificate2("Assets/rcm_pem_privkey.pkcs8")
        },
        UseTls = true,
    })
    .WithKeepAlivePeriod(TimeSpan.FromSeconds(60))
    .Build();

await manager.ConnectAsync(options, CancellationToken.None);

我总是有这个与加密相关的错误。

<Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Cannot find the requested object.

I would like to replicate this Python code sample with MQTTnet.

client = mqtt.Client(str(uuid4()))
current = dirname(__file__)
cerfile = join(current, "rcm_certchain_pem.cer")
keyfile = join(current, "rcm_pem_privkey.pkcs8")
context = create_default_context(Purpose.CLIENT_AUTH)
context.load_cert_chain(cerfile, keyfile)
client.tls_set_context(context)
client.tls_insecure_set(True)
client.connect("192.168.1.X", 1234)

I tried this with MQTTnet.

var manager = new MqttFactory().CreateMqttClient();
var options = new MqttClientOptionsBuilder()
    .WithCleanSession()
    .WithClientId(Guid.NewGuid().ToString())
    .WithTcpServer(address, port)
    .WithTls(new MqttClientOptionsBuilderTlsParameters()
    {
        AllowUntrustedCertificates = true,
        Certificates = new List<X509Certificate>
        {
            new X509Certificate2("Assets/rcm_certchain_pem.cer"),
            new X509Certificate2("Assets/rcm_pem_privkey.pkcs8")
        },
        UseTls = true,
    })
    .WithKeepAlivePeriod(TimeSpan.FromSeconds(60))
    .Build();

await manager.ConnectAsync(options, CancellationToken.None);

I always have this crypto related error.

<Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Cannot find the requested object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情深已缘浅 2025-01-26 13:47:50

MQTTNET Wiki(这不是您想要的)中记录的示例假定您有一个PFX(PKCS12)文件...它与您的键 +证书的内容相同,只是包装的方式不同。

我尝试的是以编程方式创建PFX,将其添加到X509Certificate2的列表中,然后将其分配给MQTTClientOptionsBuilderTlsParameters.Certificates。笨拙,但它起作用。代码样本:

var mqttClientOptions = new MqttClientOptionsBuilder().
    WithTcpServer(mybrokerhostname.com, 8883).
    WithClientId(goofy-client-id)
);

MqttClientOptionsBuilderTlsParameters tlsParams = new MqttClientOptionsBuilderTlsParameters();

if (connectionData.VerifyCertificateChain)
{
    byte[]? caCertFile = null;
    X509Certificate2? caCert = null;
    caCertFile = File.ReadAllBytes(connectionData.CaCertFilePath);
    caCert = new X509Certificate2(caCertFile);
    //Validate the server certificate using the user supplied CA certificate file.
    tlsParams.UseTls = true;
    tlsParams.CertificateValidationHandler = (certContext) =>
    {
          X509Chain chain = new X509Chain();
          chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
          chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
          chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
          chain.ChainPolicy.VerificationTime = DateTime.Now;
          chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
          chain.ChainPolicy.CustomTrustStore.Add(caCert);
          chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;

          // convert provided X509Certificate to X509Certificate2
          var x5092 = new X509Certificate2(certContext.Certificate);
          return chain.Build(x5092);
     };
}
else
{
     //Don't bother verifying whether the server certificate is valid.
     tlsParams.UseTls = true;
     tlsParams.CertificateValidationHandler = _ => true;
}

List<X509Certificate2> clientCerts = new List<X509Certificate2>();
X509Certificate2? clientCert = null;
clientCert = X509Certificate2.CreateFromEncryptedPemFile(connectionData.ClientCertFilePath, connectionData.ClientKeyPassword, connectionData.ClientKeyFilePath);
var clientCertPFX = new X509Certificate2(clientCert.Export(X509ContentType.Pkcs12));
clientCerts.Add(clientCertPFX);
tlsParams.Certificates = clientCerts;
mqttClientOptions.WithTls(tlsParams);

The example documented in the MQTTnet Wiki (which is not what you want) presumes you have a PFX (PKCS12) file ... which is the same content as your Key + Cert, just packaged differently.

What I tried was to create the PFX programmatically, add it to a List of X509Certificate2 and then assign THAT to to MqttClientOptionsBuilderTlsParameters.Certificates. Clunky, but it works. Code sample:

var mqttClientOptions = new MqttClientOptionsBuilder().
    WithTcpServer(mybrokerhostname.com, 8883).
    WithClientId(goofy-client-id)
);

MqttClientOptionsBuilderTlsParameters tlsParams = new MqttClientOptionsBuilderTlsParameters();

if (connectionData.VerifyCertificateChain)
{
    byte[]? caCertFile = null;
    X509Certificate2? caCert = null;
    caCertFile = File.ReadAllBytes(connectionData.CaCertFilePath);
    caCert = new X509Certificate2(caCertFile);
    //Validate the server certificate using the user supplied CA certificate file.
    tlsParams.UseTls = true;
    tlsParams.CertificateValidationHandler = (certContext) =>
    {
          X509Chain chain = new X509Chain();
          chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
          chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
          chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
          chain.ChainPolicy.VerificationTime = DateTime.Now;
          chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
          chain.ChainPolicy.CustomTrustStore.Add(caCert);
          chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;

          // convert provided X509Certificate to X509Certificate2
          var x5092 = new X509Certificate2(certContext.Certificate);
          return chain.Build(x5092);
     };
}
else
{
     //Don't bother verifying whether the server certificate is valid.
     tlsParams.UseTls = true;
     tlsParams.CertificateValidationHandler = _ => true;
}

List<X509Certificate2> clientCerts = new List<X509Certificate2>();
X509Certificate2? clientCert = null;
clientCert = X509Certificate2.CreateFromEncryptedPemFile(connectionData.ClientCertFilePath, connectionData.ClientKeyPassword, connectionData.ClientKeyFilePath);
var clientCertPFX = new X509Certificate2(clientCert.Export(X509ContentType.Pkcs12));
clientCerts.Add(clientCertPFX);
tlsParams.Certificates = clientCerts;
mqttClientOptions.WithTls(tlsParams);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文