示例代码:C# MQTTS双向认证(客户端)(服务器EMQX)

server/2025/2/12 13:24:26/

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客


目录

CA证书、客户端证书和私钥

emqx%E7%9A%84MQTTS%E8%AE%BE%E7%BD%AE-toc" style="margin-left:0px;">emqxMQTTS设置

客户端代码


CA证书、客户端证书和私钥

        使用单向认证时客户端只需要确认服务器证书有效(也可以不确认),一般服务器自签名证书需要将服务器证书的签发者CA的证书放在客户机的受信任的证书签发机构里或程序直接读取CA证书文件。

        证书包含公钥和CA的签名,别人通过验证证书正确性来确认你的身份,与证书对应的私钥则用来解密别人发给你的加密数据(用证书里的公钥加密,只有对应的私钥才能解密,这保证了只有你可以解密)。

        CA证书原则上可以通过操作系统预置加上互联网检索来验证,但是很多时候用的是自签名的CA证书,上互联网验证是没用的,需要手动安装证书告诉操作系统这个证书我认可或者程序直接读取证书文件。

        双向认证时服务端也要确认客户端的证书,因此客户端需要提供客户端证书和签发者的证书,并且客户端证书的签发机构也必须在服务器的受信任名单里。

        一般情况下我们用服务器给的客户端证书,编程的时候需要的就是服务端给的CA证书(同时也是服务器证书的签发者)和客户端证书。

        windows上包含私钥的证书多用pfx格式,unix/linux上则多用pem格式。格式的问题很头疼,我只能说我下面演示的代码在windows上正确执行了,不代表在linux上也能正确执行。

        很多库使用三个文件:CA证书、证书、私钥,CA证书文件其实可以包含多个根证书,后两个是服务器或客户端的证书和私钥,多为pem格式。如果使用pfx格式就只需要两个文件:CA证书和pfx文件(同时包含证书和私钥)。

        单独的证书和私钥多用.cer、.key的扩展名,其实格式一般也是pem文件,扩展名不同而已。pem文件格式可以包含多个私钥、证书(简单地堆进去即可)。

        从两个pem生成一个pfx:

openssl pkcs12 -export -out client.pfx -inkey client.key -in client.cer

        其中key和cer都是pem格式(有时候也用pem后缀名)。 

emqx%E7%9A%84MQTTS%E8%AE%BE%E7%BD%AE">emqxMQTTS设置

        在浏览器里设置:

        点击一下监听器的名称,右侧会显示详情,往下拉,重点在下面:

        “验证服务器证书”开关打开才能选择证书文件,这几个证书是emqx安装的时候自带的。感觉这个“服务器”其实是客户端的意思,MQTT概念里并没有服务器、客户端,只有代理(broker)、发布者、订阅者。

        verify_none不验证客户端证书,verify_peer验证客户端证书。

        “Fail If No Peer Cert”这个选项有点坑,如果前面不是verify_peer,而客户端没有客户端证书,这个选项为true就一定会导致连接失败。按照常理既然选择可不验证客户端,那么这个选项应该被忽略才对。

        上图的设置效果是必须使用双向验证。

客户端代码

//参数对象
MqttClientOptionsBuilder mqttClientOptions = new();//常规的IP端口等参数_ = mqttClientOptions.WithTcpServer(hostname, port)//.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311).WithClientId(client_id).WithCleanSession(false).WithKeepAlivePeriod(TimeSpan.FromSeconds(30)).WithCredentials(userid, passwd);//构造认证所需的参数X509Certificate2 caCert = new(caCertpath);//受信任的CA证书文件X509Certificate2 clientCert = new(clientCertpath);//客户端证书和私钥,如果是密码保护的pfx文件,可以用(.pfx,passwd)var newCert = new X509Certificate2(clientCert.Export(X509ContentType.SerializedCert));//怀疑这步就是为了去掉密码保护X509Certificate2Collection certificates = [];_ = certificates.Add(caCert);_ = certificates.Add(newCert);MqttClientTlsOptions tlsOptions = new MqttClientTlsOptions{UseTls = true,AllowUntrustedCertificates = false,SslProtocol = SslProtocols.None, //根据需要选择 TLS 版本,None表示系统选择,Default已经废弃 ClientCertificatesProvider = new DefaultMqttCertificatesProvider(certificates),//加载证书CertificateValidationHandler = ValidateCertifiCertificates//避免证书验证,关键!没这个连接不返回也不报异常};_ = mqttClientOptions.WithTlsOptions(tlsOptions); // tls选项//连接,用的是MQTTnet.Client
public IMqttClient mqttClient;
mqttClient.ConnectAsync(mqttClientOptions.Build());

(这里是文档结束)


http://www.ppmy.cn/server/167070.html

相关文章

第二章:QT核心机制(二)

作业 1> 将鼠标事件和键盘事件相关代码重新实现一遍 //头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QKeyEvent> //键盘事件类 #include <QDebug> #include <QLabel> #include <QMouseEvent> …

物联网综合性应用之网关设计

最近由于项目的需要&#xff0c;设计了一款基于rv1106的物联网网关 该产品需要集合IOT功能 BLE定位 能耗监测io控制等&#xff0c;音视频通话&#xff08;基于webrtc&#xff09; 由于概念机阶段不想自己开板于是乎找到万能的淘宝相中了顶配版的luckfox pico w. 理由是 1 、…

软考通过率仅有10% ?或许2025年更难?

软考的通过率是有具体数据的&#xff0c;各地的通过率在其他帖子中都有提及&#xff0c;这里就不再赘述了。 总体来说&#xff0c;中级的通过率大约在20%-25%之间&#xff0c;高级的通过率在10%-15%左右。 从这个数据来看&#xff0c;怎么也不能算高吧。 然而&#xff0c;网…

Java基础知识总结(四十八)--TCP传输、TCP客户端、TCP服务端

**TCP传输&#xff1a;**两个端点的建立连接后会有一个传输数据的通道&#xff0c;这通道称为流&#xff0c;而且是建立在网络基础上的流&#xff0c;称之为socket流。该流中既有读取&#xff0c;也有写入。 **tcp的两个端点&#xff1a;**一个是客户端&#xff0c;一个是服务…

22.3、IIS安全分析与增强

目录 IIS安全威胁分析iis安全机制iis安全增强 IIS安全威胁分析 iis是微软公司的Web服务软件&#xff0c;主要提供网页服务&#xff0c;除此之外还可以提供其他服务&#xff0c;第一个最主要的是网页服务&#xff0c;第二个是SMTP邮件服务&#xff0c;第三个是FTP文件传输服务。…

ES传输带宽优化方案

背景&#xff1a;目前日志从kafka中消费后转存ES,是通过批量发送的方式打入ES&#xff0c;但是如果数据量很大那么就会占用很多的带宽&#xff0c;而目前正在降本增效&#xff0c;无法增加带宽或者服务节点。 源码在最下方&#xff01;&#xff01; 限流牺牲磁盘作为代价 从…

C语言基础11:分支结构以及if的使用

C语言基础 内容提要 分支结构 条件判断用if语句实现分支结构 分支结构 问题抛出 我们在程序设计往往会遇到如下问题&#xff0c;比如下面的函数的计算&#xff1a; y { 1 / x 当 x ≠ 0 时 10000 当 x 0 时 y \begin{cases} 1/x \quad当x\neq0时\\ \\ 10000 \quad当x0…

uni getLocation 公众号h5获取定位坐标没有返回

先看代码 //获取经纬度getLocation() {console.log("111")uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&#xff1a; res.longitude);console.log(当前位置的纬度&#xff1a; res.latitude);},fail: function(err) {conso…