如何使用 QtMqtt 和 SSL 执行安全 MQTT?

2024-04-07

我正在尝试使用 QtMQtt 示例项目 simpleclient。但我想执行安全的 MQTT。我该如何处理这个问题?

我读过这篇博客(https://www.qt.io/blog/2017/08/14/introducing-qtmqtt-protocol https://www.qt.io/blog/2017/08/14/introducing-qtmqtt-protocol)。但这对我没有多大帮助。

我是否必须使用 QsslSocket 的 connectToHostEncrypted() 还是应该使用 QTMQTT 客户端的 connectToHostEncrypted()

如果我使用 QTMQTT 客户端的 connectToHostEncrypted()。它只允许我设置 sslpeername。它不允许我设置证书或私钥

或者如果我使用 QSSLSOCKECT 的 connectToHostEncrypted()。如何通知我的 MQTT 客户端已建立连接。我现在应该能够发布和订阅

现在写我正在做这样的事情:

connect(this->(QSslSockets's Object),SIGNAL(encrypted),this, SLOT(foo()))
void foo()
{
QTMQTTClient's object->connectToHostEncrypted("Hostname")
}

这不允许我发布或订阅。 如果有人能指出我正确的方向。一些文档或示例对我确实有很大帮助


QMqttClient https://doc.qt.io/QtMQTT/qmqttclient.html如果您的 Qt 支持 SSL,将用作 QSslSocket 的传输设备,以验证它是否支持 SSLQSslSocket::supportsSsl() https://doc.qt.io/qt-5/qsslsocket.html#supportsSsl函数必须返回 true。如果不支持,则必须按照指南启用它:启用和禁用 SSL 支持 https://doc.qt.io/qt-5/ssl.html#enabling-and-disabling-ssl-support.


考虑到上述方法有效,那么您可以全局设置证书,以便所有 QSslSocket 默认使用它:

QSslCertificate cert = QSslCertificate(...);
QSslSocket::addDefaultCaCertificate(cert);

QMqttClient client;
client.setHostname(...);
client.setPort(...);
// ...
client.connectToHostEncrypted();

例如使用http://test.mosquitto.org/ http://test.mosquitto.org/:

#include <QtMqtt>

const QByteArray pem = R"(-----BEGIN CERTIFICATE-----
MIIC8DCCAlmgAwIBAgIJAOD63PlXjJi8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
VQQGEwJHQjEXMBUGA1UECAwOVW5pdGVkIEtpbmdkb20xDjAMBgNVBAcMBURlcmJ5
MRIwEAYDVQQKDAlNb3NxdWl0dG8xCzAJBgNVBAsMAkNBMRYwFAYDVQQDDA1tb3Nx
dWl0dG8ub3JnMR8wHQYJKoZIhvcNAQkBFhByb2dlckBhdGNob28ub3JnMB4XDTEy
MDYyOTIyMTE1OVoXDTIyMDYyNzIyMTE1OVowgZAxCzAJBgNVBAYTAkdCMRcwFQYD
VQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwGA1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1v
c3F1aXR0bzELMAkGA1UECwwCQ0ExFjAUBgNVBAMMDW1vc3F1aXR0by5vcmcxHzAd
BgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hvby5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAMYkLmX7SqOT/jJCZoQ1NWdCrr/pq47m3xxyXcI+FLEmwbE3R9vM
rE6sRbP2S89pfrCt7iuITXPKycpUcIU0mtcT1OqxGBV2lb6RaOT2gC5pxyGaFJ+h
A+GIbdYKO3JprPxSBoRponZJvDGEZuM3N7p3S/lRoi7G5wG5mvUmaE5RAgMBAAGj
UDBOMB0GA1UdDgQWBBTad2QneVztIPQzRRGj6ZHKqJTv5jAfBgNVHSMEGDAWgBTa
d2QneVztIPQzRRGj6ZHKqJTv5jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
A4GBAAqw1rK4NlRUCUBLhEFUQasjP7xfFqlVbE2cRy0Rs4o3KS0JwzQVBwG85xge
REyPOFdGdhBY2P1FNRy0MDr6xr+D2ZOwxs63dG1nnAnWZg7qwoLgpZ4fESPD3PkA
1ZgKJc2zbSQ9fCPxt2W3mdVav66c6fsb7els2W2Iz7gERJSX
-----END CERTIFICATE-----
)";

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    const QString hostname{"test.mosquitto.org"};
    const quint16 port = 8883;
    const QMqttTopicName topic{"qtmqtt/ssl_test"};
    const QMqttTopicFilter filter{"qtmqtt/#"};

    QSslCertificate cert = QSslCertificate(pem, QSsl::Pem);
    QSslSocket::addDefaultCaCertificate(cert);

    QMqttClient client;
    client.setHostname(hostname);
    client.setPort(port);

    QObject::connect(&client, &QMqttClient::stateChanged, [](QMqttClient::ClientState state){
        if(state == QMqttClient::Disconnected)
            qDebug() << " State: Disconnected";
        else if(state == QMqttClient::Connecting)
            qDebug() << " State: Connecting";
        else if(state == QMqttClient::Connected)
            qDebug() << " State: Connected";
    });

    QObject::connect(&client, &QMqttClient::errorChanged, [](QMqttClient::ClientError error){
        qDebug() << error;

    });

    QObject::connect(&client, &QMqttClient::messageReceived, [](const QByteArray &message, const QMqttTopicName &topic){
        qDebug() << " Received Topic:" << topic.name() << " Message: " << message;
    });

    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, [&client, &topic](){
        if(client.publish(topic,  QDateTime::currentDateTime().toString().toUtf8()) == -1)
            qDebug() << "Error: Could not publish message";
    });

    QObject::connect(&client, &QMqttClient::connected, [&client, &timer, &filter](){
        QMqttSubscription *subscription = client.subscribe(filter);
        if(!subscription)
            qDebug() << "Could not subscribe";
        timer.start(1000);
    });

    client.connectToHostEncrypted();

    return a.exec();
}

Output:

 State: Connecting
 State: Connected
 Received Topic: "qtmqtt/ssl_test"  Message:  "Sat Sep 7 00:58:08 2019"
 Received Topic: "qtmqtt/ssl_test"  Message:  "Sat Sep 7 00:58:09 2019"
 Received Topic: "qtmqtt/ssl_test"  Message:  "Sat Sep 7 00:58:10 2019"
 Received Topic: "qtmqtt/ssl_test"  Message:  "Sat Sep 7 00:58:11 2019"
 Received Topic: "qtmqtt/ssl_test"  Message:  "Sat Sep 7 00:58:12 2019"
 ...

您还可以使用 QSslConfiguration 设置证书和/或私钥:

QSslCertificate cert = QSslCertificate(...);
QSslConfiguration conf;
conf.setCaCertificates({cert});
// conf.setPrivateKey();
QSslConfiguration::setDefaultConfiguration(conf);

QMqttClient client;
client.setHostname(...);
client.setPort(...);
// ...
client.connectToHostEncrypted();

你也可以通过将QSslSocket设置为传输设备来直接传递它:

QSslCertificate cert = QSslCertificate(...);
QSslSocket socket;
socket.addCaCertificate(cert);
// conf.setPrivateKey();

QMqttClient client;
client.setHostname(...);
client.setPort(...);
client.setTransport(&socket, QMqttClient::SecureSocket);
// ...
client.connectToHostEncrypted();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 QtMqtt 和 SSL 执行安全 MQTT? 的相关文章

  • C++ 中的可变参数函数声明中省略了逗号

    我习惯于这样声明可变参数函数 int f int n 读书时C 编程语言我发现书中的声明省略了逗号 int f int n the comma has been omitted 这个语法似乎是 C 特定的 因为当我尝试使用 C 编译器编译它
  • 仅使用 1 行 C++ 初始化 2d 向量

    我需要能够初始化一个 2D 向量 int同一条线我在其中创建它 更具体地说 我必须创建一个3x2大小 2D 向量并将其所有值设置为 0 仅使用1行代码 有没有一种方法可以在不使用 for 循环和几行代码的情况下完成此操作 尝试这个 std
  • 将文件扩展名与应用程序关联

    我编写了一个编辑特定文件类型的程序 我想为用户提供在启动时将我的应用程序设置为该文件类型的默认编辑器的选项 因为我不需要安装程序 我尝试编写一个可重用的方法 通过向 HKEY CLASSES ROOT 添加一个键来为我关联一个文件 最好在任
  • LockBits 性能关键代码

    我有一个方法需要尽可能快 它使用不安全的内存指针 这是我第一次尝试这种类型的编码 所以我知道它可能会更快
  • 如何从 UNC 中提取服务器名称

    谁能告诉我如何从 UNC 中提取服务器名称 ex 服务器名称 目录 目录 编辑 我很抱歉 但看起来我需要澄清一个错误 路径实际上更像是 服务器名 d 目录 我知道这可能会改变一些事情 怎么样Uri Uri uri new Uri serve
  • 一个阻塞但非模态的 QDialog?

    我有一堆图像 我想对其执行一些操作 处理完每个图像后 我的程序应该弹出一个对话框 提示用户是否要继续处理下一个图像或中止 在此之前 他们应该有机会对图像或参数进行一些手动更改 无论如何 他们必须能够访问应用程序的窗口 而调用对话框的方法的执
  • 类模板的可变参数构造函数模板的特化

    这是一个带有可变参数构造函数的类 它专门用于从临时对象进行复制和移动 template
  • 使用正在运行的进程的共享内存收集核心转储

    核心转储仅收集进程空间 而不收集为进程间通信创建的共享内存 如何使核心转储也包含正在运行的进程的共享内存 设置核心文件过滤器 proc PID coredump filter per http man7 org linux man page
  • QT“找不到 Qt 平台插件“xcb””

    我出于学术原因安装了QT everywhere 5 15开源版 但无法运行程序 首先 我编译了必要的源文件make并安装了QT Creator 然后我选择qmake来运行其中的程序 当我尝试运行示例程序时 遇到以下错误 qt qpa plu
  • 策略模式的现实示例

    我一直在读关于OCP原理 http en wikipedia org wiki Open closed principle以及如何使用策略模式来实现这一目标 我打算尝试向几个人解释这一点 但我能想到的唯一例子是根据 订单 的状态使用不同的验
  • 您在 C# 或 .NET 中见过的最奇怪的极端情况是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何将焦点设置到 Windows 窗体应用程序中的控件?

    在 Windows 窗体应用程序中 when我是否编写代码以在应用程序启动时以及随后调用函数后将焦点设置到控件 例如 如果我有一个 DropDownList 一个 TextBox 和四个按钮 并且我希望将 Focus 设置为 DropDow
  • gcc总是做这种优化吗? (公共子表达式消除)

    作为示例 假设表达式sys gt pot atoms item gt P kind mass在循环内求值 循环只改变item 因此表达式可以简化为atoms item gt P kind mass通过将变量定义为atoms sys gt p
  • 在 C、C++ 中实现腐蚀、膨胀

    我对二值图像的膨胀是如何完成的有理论上的了解 AFAIK 如果我的 SE 结构元素 是这样的 0 1 1 1 在哪里 代表中心 我的图像 二进制是这样的 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0
  • invoke_result获取模板成员函数的返回类型

    如何获取模板成员函数的结果类型 下面的最小示例说明了该问题 include
  • 使用 std::set 时重载运算符<

    这是我第一次使用 std set 容器 并且我对操作符 std less 遇到了问题 我声明该集合 std set
  • 如何检查多个变量是否等于同一值?

    如何比较多个项目 例如 我希望检查所有变量 A B 和 C 是否都等于字符 X 或所有三个变量都等于 O 如果其中 2 个为 X 1 个为 O 则应返回 false I tried if A B C X A B C O Do whateve
  • 如果 foreach 是一个结构数组,它会复制每个元素吗?

    我有一个结构数组 做foreach运算符在迭代数组时复制每个元素 据我所理解foreach只是底层的语法糖转换为for 所以看来答案是否定的 但我很想得到一些确认 PS 看来应该有人已经问过了 但我无法轻易找到任何东西 因此 请以提供的参考
  • C 警告函数调用中缺少标记

    这是我的警告 Missing sentinel in function call 我怎样才能删除它 我正在使用 linux 和 gcc 编译器 看来您可能没有终止数组声明NULL 如果没有 null 您可能会遇到一些内存怪异 因为运行时将不
  • C# 泛型中的通配符等效项

    假设我有一个通用类 如下所示 public class GeneralPropertyMap

随机推荐

  • 使用 ng-change、AngularJS 进行日期输入验证

    我正在使用 AngularJS 和AngularJS 引导程序 http angular ui github io bootstrap 在我的页面中 我有一个日期选择器指令 如下所示 div class p class input grou
  • ASP.NET 5 Identity 3 用户在应用程序重新启动后注销

    我们正在使用 ASP NET Identity 3 我们的用户会随机自动注销 为了重现此问题 我尝试重新启动应用程序 所有用户都退出 即使是那些已检查过的用户Remember me 它只发生在生产中 在开发环境中运行良好 Update 我们
  • R 包拼凑:行/列标题

    有没有办法使用 patchwork 包按行或列添加标题来组合绘图 前任 安排为 拼凑 是的 有一种方法可以在生成的图的排列中放置行或列的标签patchwork通过使用textGrob正如评论之一所建议的 p1 lt ggplot iris
  • $this->post codeigniter 不适用于其余 api

    我尝试与 this gt post 获取以 json 格式通过 post 发送的数据 例如 我无法得到任何结果 this gt post name 这是代码
  • Python“正则表达式”模块:模糊值

    我正在使用 模糊匹配 功能Regex https pypi python org pypi regex 模块 如何获得 匹配 的 模糊度值 它指示模式与字符串的差异程度 就像 Levenshtein 中的 编辑距离 一样 我以为我可以获取
  • 添加 const 泛型时的“不受约束的泛型常量”

    我如何添加 const 泛型 假设我有一个 foo 类型 pub struct foo
  • 如果类型参数的顺序错误,是否可以将类型设为类的实例?

    考虑以下类型 data SomeType m a SomeType m Integer a 我们可以使用以下代码轻松地将该类型设为 Functor 的实例 instance Functor SomeType m where fmap f S
  • 使用递归函数进行并行编程?

    问题背景 我正在尝试编写一个利用多核处理器和并行处理的难题解决算法 然而 理想 最简单的解决方案是简单的递归函数 分解解决方案以利用并行处理的最佳方法是什么AND递归函数 下面的代码是一个简单的解谜算法的解决方案 它工作正常 此示例中的谜题
  • 如何使用java将阿拉伯语单词插入mysql数据库

    我有一个java应用程序 想要将阿拉伯语单词插入mysql数据库 我的代码如下 Connection con null String url jdbc mysql localhost String db students String dr
  • 如何自定义 YouTube 视频的结束时间?

    我正在尝试弄清楚如何为嵌入的 YouTube 视频指定自定义结束时间 我知道我可以通过添加来自定义开始时间开始 30 但我还没有看到任何与结束时间有关的内容 我需要能够为我正在构建的网络应用程序执行此操作 因此如果 YouTube 无法提供
  • Jekyll 插件不工作

    我开发了一个简单的 Jekyll 插件 用于生成类别页面 它在我的本地系统上运行良好 但在 github 站点上不起作用 这是插件的来源 https github com madhur madhur github com blob mast
  • 对于新 XPage 开发人员来说,最重要的 3 个 XPage 性能技巧是什么?

    您会告诉刚接触 XPage 的开发人员做哪 3 件事 以帮助最大限度地提高 XPage 应用程序的性能 Tim Tripcony 给出了很多建议
  • 如何使用 Drive Rest API 读取云端硬盘照片

    我正在尝试使用 Google Apps 脚本中的 Drive REST API 读取 Google Photos 代码如下所示 function myFunction var files Drive Files list maxResult
  • Microsoft.Owin.Cors 中间件与 ASP.NET Web Api 2.0 一起使用时会做什么?

    我有一个带有令牌身份验证的 ASP NET Web Api 2 0 项目 所有内容主要按照本文完成 使用 ASP NET Web API 2 Owin 和 Identity 进行基于令牌的身份验证 http bitoftech net 20
  • ASP.NET MVC 性能

    我发现一些疯狂的评论称 ASP NET MVC 比 ASP NET WebForms 快 30 倍 真正的性能差异是什么 是否经过测量以及性能优势是什么 这是为了帮助我考虑从 ASP NET WebForms 迁移到 ASP NET MVC
  • 将 Docker 容器限制为单个 cpu 核心

    我正在尝试构建一个在一致条件下运行代码片段的系统 我认为实现这一点的一种方法是在具有相同布局的 docker 容器中运行各种程序 保留相同数量的内存等 但是 我似乎不知道如何保持 CPU 使用率一致 我似乎能找到的最接近的是 cpu 共享
  • 压缩过滤器+MVC+Yahoo YSlow

    我一直在使用雅虎的 YSLOW 来尝试让我的页面运行得更快AgentX http www agentx co nz 我正在使用下面的压缩过滤器 当我通过 Visual Studio 运行该网站时 YSLOW 说所有文件都已压缩 当我查看实时
  • C#:从 XML 读取/写入日期时间

    我需要知道写作 阅读的最佳方式DateTime传入 传出 XML 我应该直接写吗DateTime转换为 XML 或DateTime ToString 转换为 XML 第二个问题是如何从 XML 中读取日期元素 铸造可以用于此目的吗 例如 D
  • RxJS (5.0rc4):暂停和恢复间隔计时器

    我正在使用 Rx 来保持动画时钟 每个动画帧都会将间隔刻度映射到该刻度的新值 假设我想暂停动画 最自然的方法是以某种方式暂停时钟接收 然后在稍后恢复它 取消订阅然后重新订阅并不是一个自然的选择 因为这个动画时钟是一个冷可观察的对象 我不想在
  • 如何使用 QtMqtt 和 SSL 执行安全 MQTT?

    我正在尝试使用 QtMQtt 示例项目 simpleclient 但我想执行安全的 MQTT 我该如何处理这个问题 我读过这篇博客 https www qt io blog 2017 08 14 introducing qtmqtt pro