Qt中使用OpenSSL

本文介绍了Qt如何使用OpenSSL进行HTTPS通信,包括Qt对OpenSSL的依赖、版本匹配以及动态加载。同时,讨论了OpenSSL的法律限制、版本变更以及旧版本的SSL漏洞问题,并给出了安全版本的选择策略。此外,还提到了Qt中涉及SSL的类和功能,以及安装OpenSSL的方法,包括源码编译和第三方安装包。最后,文章提醒开发者关注OpenSSL的安全更新,确保项目的安全性。
摘要由CSDN通过智能技术生成

概述

OpenSSL官网

Qt官方文档:

网站内容为英文,阅读起来需要一些耐心。其中比较重要的信息有两点:

  • Qt使用了OpenSSL,但是因为地区法律规定的原因,在Qt安装包里面并没有包含OpenSSL,需要用的话,在遵守法律的前提下,自己编译安装,并对你的软件合法分发。
    这里说的“法律”,OpenSSL官网在首页最下方对其进行了描述(来自必应翻译):

请记住,在世界某些地区,进出口和/或使用强大的加密软件、提供加密钩,甚至只是传达有关加密软件的技术细节都是非法的。因此,当您将此包导入您的国家/地区时,请重新分发,甚至只是通过电子邮件向作者或其他人发送技术建议,甚至提供补丁,因此强烈建议您密切关注适用于您的任何法律或法规。OpenSSL 的作者对您在此处做出的任何违规行为不承担责任。所以要小心,这是你的责任。

  • 默认情况下,Qt在运行时动态加载OpenSSL,也就是说,如果能找到对应版本的OpenSSL库,相关模块就支持SSL通信,否则就不支持。

Qt中哪些地方用到了OpenSSL

https

所属模块:QT += network

使用QNetworkAccessManager进行https访问时,需要使用OpenSSL,通过以下代码可以打印出QNetworkAccessManager当前可用的协议。

QNetworkAccessManager *manager = new QNetworkAccessManager(this);
qDebug() << manager->supportedSchemes();

如果输出中没有"https",说明OpenSSL未配置,配置方法见下文。

Qt SSL Classes

所属模块:QT += network

Qt的SSL系列类使用OpenSSL实现,所以依赖OpenSSL库。

可以使用以下代码打印查看当前版本的Qt依赖哪个版本的OpenSSL:

qDebug() << QSslSocket::sslLibraryBuildVersionString();

安装OpenSSL方式

下载安装有两种方式:

  1. 通过源码编译,直接在官网下载源码编译即可,优点是安全,全版本都有,缺点是费事。具体步骤参考:
    QT支持https及编译OpenSSL

  2. 使用第三方编译好的安装包:优点是省事,缺点是无法确定发布者是否可靠、版本不全。具体步骤参考:Qt连接https :解决OpenSSL问题

  3. Qt Creator使用到了OpenSSL,而且Qt Creator是用当前版本Qt编译的。Qt Creator.exe所在路径为: Qt安装目录/Tools/QtCreator/bin。是否可以直接到Qt Creator安装目录下去找OpenSSL的依赖库,然后拷贝过来?理论上行得通,但是实际上通常无法正常工作。因为Qt Creator一般是32位的程序,如果你的程序是64位的,那么你的程序无法使用Qt Creator的OpenSSL库。所以这种方式不通用,通常会失败。

关于libeay32.dll和ssleay32.dll

可能读者在搜索资料的过程中,发现有的地方说要拷贝libeay32.dll和ssleay32.dll,有的地方说要拷贝libssl-1_1.dll和libcrypto-1_1.dll。到底需要哪个?还是两者都要?

答案在OpenSSL git仓库日志中,找到分支OpenSSL-1_1_0-stable,查看日志,在以下提交中有对应的描述:

SHA-1: 6928b6171ada6d0de5a024a188dc7a68094d2dca
* Change names of ordinals and libs, libeay => libcrypto and ssleay => libssl
Reviewed-by: Rich Salz <rsalz@openssl.org>

也就是说,

  • libeay32.dll和ssleay32.dll是OpenSSL v1.1.0之前版本才有的库。
  • 从OpenSSL v1.1.0开始,libeay32.dll=>libcrypto,ssleay32.dll=>libssl。

关于SSL漏洞

旧版本的OpenSSL库存在漏洞,如“心脏滴血”漏洞,详细描述见OpenSSL漏洞列表。所以要尽量使用已知安全的、稳定的OpenSSL版本。对于Qt来说,也要使用新的Qt版本。

但是,如果在Qt版本确定的情况下,此版本的Qt使用的OpenSSL版本也是确定的。如果此版本的OpenSSL存在漏洞怎么办?

1. 使用此分支的稳定版本

以Qt5.5.1 msvc2013 32位为例,其依赖的OpenSSL版本为:OpenSSL 1.0.2g 1 Mar 2016。在 OpenSSL官网更新日志 中可以找到此版本的更新描述。

接着,在 OpenSSL的Git仓库 中,将其克隆到本地后查看版本分支图,可以看到OpenSSL 1.0.2g所在分支为OpenSSL_1_0_2-stable,此分支最新版本为OpenSSL 1.0.2u。因为它们属于同一个大版本,所以可以使用此版本的OpenSSL尝试,这里仅提供一个思路,笔者目前未尝试。

再以Qt 5.12.11为例,此版本使用的OpenSSL版本为OpenSSL 1.1.1g 21 Apr 2020。直接安装使用最新的OpenSSL v1.1.1l能够正常运行。

2. 更换版本分支

截至目前,根据官网描述,v1.1.1以前的版本将不做更新,也就是说,v1.1.1之前的版本就算有重大Bug也不会修复了(除非付费支持)。在这种情况下,只有更换新的OpenSSL分支了。更换OpenSSL分支一般需要更换Qt版本。

3. 使用第三方SSL通信库

可能因为某种原因,项目中无法更换Qt版本。解决此问题是方法是,使用第三方网络通信库,如:

  • libcurl:libcurl on github地址,libcurl可以基于较新的OpenSSL编译,从而实现https访问。如需要实现SSL Socket,可以查找第三方库或自己实现。

结语

至此我们对Qt中使用OpenSSL有了初步的了解,更加深入的内容后续会不断更新,敬请期待。


本文原创首发自微信公众号:Qt未来工程师

  • 12
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Qt使用OpenSSL,可以通过以下步骤实现: 1. 下载OpenSSL库 可以从OpenSSL官网下载最新版本的OpenSSL库,也可以使用系统自带的OpenSSL库。如果是在Windows平台上,可以下载预编译的OpenSSL库。 2. 配置Qt项目 在Qt项目,需要在.pro文件添加以下配置: ``` QT += network LIBS += -L/path/to/openssl/lib -lssl -lcrypto INCLUDEPATH += /path/to/openssl/include ``` 其,/path/to/opensslOpenSSL库的安装路径。通过上面的配置,可以将OpenSSL库链接到Qt项目。 3. 使用OpenSSL库 在Qt使用OpenSSL库,可以参考以下示例代码: ```c++ #include <QSslSocket> #include <QSslCertificate> #include <QSslKey> int main() { // 初始化SSL库 QSslSocket::addDefaultCaCertificate(QSslCertificate::fromPath("ca.crt")); // 创建SSL套接字 QSslSocket socket; socket.setProtocol(QSsl::TlsV1_2); // 加载客户端证书和私钥 QSslCertificate clientCert("client.crt"); QSslKey clientKey("client.key", QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "password"); socket.setLocalCertificate(clientCert); socket.setPrivateKey(clientKey); // 连接服务器 socket.connectToHostEncrypted("server.com", 443); if (!socket.waitForConnected()) { qDebug() << "Error: " << socket.errorString(); return -1; } // 发送请求数据 const char *request = "Hello, world!"; socket.write(request, strlen(request)); socket.waitForBytesWritten(); // 读取响应数据 QByteArray response; while (socket.waitForReadyRead()) { response += socket.readAll(); } qDebug() << "Received: " << response; // 关闭套接字 socket.disconnectFromHost(); socket.waitForDisconnected(); return 0; } ``` 在上面的示例,首先使用addDefaultCaCertificate函数添加了CA证书。然后创建了QSslSocket对象,并设置TLS 1.2协议。接着加载了客户端证书和私钥,并连接到服务器。在连接成功后,通过write函数发送请求数据,并通过waitForBytesWritten函数等待数据发送完成。然后通过waitForReadyRead函数等待服务器响应数据,并通过readAll函数读取响应数据。最后关闭套接字。 注意,在实际使用,需要根据实际情况修改证书和私钥的文件名、地址和端口等参数。同时,还需要处理连接错误和读写错误等异常情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撬动未来的支点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值