使用 OpenSSL 1.1.1d 静态编译 Qt 5.13.1 生成 QSslSocket::connectToHostEncrypted:TLS 初始化失败

2023-12-01

我想实现什么目标?

我需要创建一个具有 SSL 支持的便携式(一体化)应用程序。

问题是什么?

因此,我面临的核心问题是将 SSL 支持纳入我的二进制/便携式应用程序中。

A MCVE该应用程序的功能很简单:

Project .pro file

QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

Project main.cpp

#include <QCoreApplication>
#include <QSslSocket>

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

    qDebug() << "Is SSL Enabled? " << QSslSocket::supportsSsl();
    qDebug() << "SSL Library Build Version (Qt compiled against): " << QSslSocket::sslLibraryBuildVersionString();
    qDebug() << "SSL Library Version String (available locally): " << QSslSocket::sslLibraryVersionString();

    return a.exec();
}

  • 输出在我的开发机:

    Is SSL Enabled?  true
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  "OpenSSL 1.1.1d  10 Sep 2019"

开发机信息

    C:\Users\cybex>echo %PATH%
    C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin

    C:\Users\cybex>openssl
    WARNING: can't open config file: /z/extlib/_openssl_/ssl/openssl.cnf
    OpenSSL> version
    OpenSSL 1.0.2g  1 Mar 2016

  • 在新的 Windows 10 x86 计算机上运行相同的二进制文件会导致:

    Is SSL Enabled?  false
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  ""

试验机信息(完全全新安装 - Windows 10 x86)

    C:\Users\cybex>echo %PATH%
    C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
    C:\Users\cybex>openssl
    'openssl' is not recognized as an internal or external command,
    operable program or batch file.

  • 在新的 Windows 7 x64 计算机上运行相同的二进制文件会导致:

    Is SSL Enabled?  false
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  ""

试验机信息(已安装驱动程序的 Windows 7 x64 笔记本电脑)

    C:\Users\Home>echo %PATH%
    C:\Program Files (x86)\OpenSSL\libs;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files (x86)\OpenSSL\libs;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\
    C:\Users\Home>openssl
    'openssl' is not recognized as an internal or external command, operable program or batch file.

通过查看上面的结果,我得出结论,安装OpenSSL可以解决问题。很好,但我希望将其包含在我的便携式应用程序中。

为了实现这一目标,我需要

  1. 使用 OpenSSL 支持静态编译 Qt

我在以下人员的帮助下做到了这一点这个脚本改编自ps1 powershell脚本 found 在 Qt 的 wiki 上。我做了补充:

  • OpenSSL 主页$OPENSSL_HOME

  • 线程数$threads, and

  • 架构类型$arch要使用的。

配置如下:

cmd /C "configure.bat -static -debug-and-release -platform win32-g++ -prefix $QtDir `
        -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -sql-sqlite -ssl -openssl -I $($OPENSSL_HOME)\include -L$($OPENSSL_HOME)\lib\MinGW`
        -opensource -confirm-license `
        -make libs -nomake tools -nomake examples -nomake tests -v"
cmd /C "mingw32-make -k -j$($threads)"

Note 1:

我在用-openssl并不是-openssl-linked。我尝试过用这两种方法构建 Qt 的几种变体-openssl and -openssl-linked. -openssl-linked永远无法成功构建,请参阅这个帖子我提出了原因。

Note 2:

我唯一成功的静态 Qt 编译是-ssl -openssl启用配置标志

OpenSSL 安装位于

`$OPENSSL_HOME = "C:\OpenSSL-Win32"` 

我使用 MinGW 库的地方,可以在

`$OPENSSL_HOME = "C:\OpenSSL-Win32\lib\MinGW",`

与文件

Directory: C:\OpenSSL-Win32\lib\MinGW

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019/09/11     18:11        3347286 libcrypto.a
-a----       2019/09/11     18:10         109020 libcrypto.def
-a----       2019/09/11     18:11         385126 libssl.a
-a----       2019/09/11     18:10          14033 libssl.def
  1. 将链接项目 .pro 添加到 OpenSSL 库

我将 OpenSSL 库添加到.pro文件(使用针对 OpenSSL 1.1.1d 构建的预编译 Qt - 如上所示)

QT -= gui
QT += network

INCLUDEPATH += "C:\OpenSSL-Win32\include"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libssl.a"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libcrypto.a"

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

Note 3

带有和不带有上述链接库的二进制大小保持相同的大小

上面添加的库的二进制文件(在我的开发机器上)的 LDD 输出是:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

上面添加了库的二进制文件(在我的 Windows 10 x86 测试机上)的 LDD 输出是:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\Desktop\SSL-Test.exe
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

Both SSL info输出是相同的

在非开发计算机上请求 SSL 连接时的输出是

QSslSocket::connectToHostEncrypted:TLS 初始化失败

这是未包含 OpenSSL 库的结果。

所以基本上,将静态 OpenSSL 库添加到项目文件中不起作用,或者我做得不正确?


OpenSSL 线程本地存储由每个 Qt 源代码的“加载的库”来预测。然后,您需要确保库与可执行文件静态链接或通过路径访问。

if (!supportsSsl()) {
    qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
    d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
    return;
}

那么呢supportsSsl()?

/*!
    \internal

    Does the minimum amount of initialization to determine whether SSL
    is supported or not.
*/

bool QSslSocketPrivate::supportsSsl()
{
    return ensureLibraryLoaded();
}

But根据 Qt 源代码,“库加载”是一个有点“更深”的概念:

bool QSslSocketPrivate::ensureLibraryLoaded()
{
    if (!q_resolveOpenSslSymbols())
        return false;

    const QMutexLocker locker(qt_opensslInitMutex);

    if (!s_libraryLoaded) {
        // Initialize OpenSSL.
        if (q_OPENSSL_init_ssl(0, nullptr) != 1)
            return false;
        q_SSL_load_error_strings();
        q_OpenSSL_add_all_algorithms();

        QSslSocketBackendPrivate::s_indexForSSLExtraData
            = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
                                        nullptr, nullptr);

        // Initialize OpenSSL's random seed.
        if (!q_RAND_status()) {
            qWarning("Random number generator not seeded, disabling SSL support");
            return false;
        }

        s_libraryLoaded = true;
    }
    return true;
}

只要这不是远程调试会话,并且这个问题的答案很重要,您需要使用符号在 DEBUG 模式下构建 Qt 库(或准备使用符号进行 DEBUG 构建),然后简单地在此函数中放置一个断点并找到阻止 Qt 应用程序使用 OpenSSL 的最后一个细节。

调试器的答案应该指出“TLS 初始化失败”的原因。

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

使用 OpenSSL 1.1.1d 静态编译 Qt 5.13.1 生成 QSslSocket::connectToHostEncrypted:TLS 初始化失败 的相关文章

  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 如何在 C# 中从 UNIX 纪元时间转换并考虑夏令时?

    我有一个从 unix 纪元时间转换为 NET DateTime 值的函数 public static DateTime FromUnixEpochTime double unixTime DateTime d new DateTime 19
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • 私有模板函数

    我有一堂课 C h class C private template
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 使用 WebView android 读取 Gif 图像

    当我尝试使用 Android 2 3 3 API 10 中的 WebView 读取 gif 图像时 它不是动画的 它显示为静态的 我该如何解决这个问题 有什么我必须更改的设置吗 Activity Main xml
  • Python 中的命名反向引用 (?P=name) 问题

    我在学习 re Python 的一部分 以及命名模式 P name 使我困惑 当我使用re sub 为了对数字和字符进行一些交换 模式 P name 不起作用 但模式 N and g
  • 有条件终止 SAS

    如果满足特定条件 我试图停止 SAS 程序的处理 我创建了一个宏变量 如果该变量 gt 0 5 那么我想要硬停止程序 当前程序看起来像 data a1 set Server a2 run macro1 a1 macro2 t1 t1 gen
  • 实体表不是使用 JPA 2.1 创建的

    我在 Netbeans 中使用 JPA 2 1 来创建我的实体 如果我的数据库没有表 那么它应该从实体创建表 当我部署并运行企业应用程序时 userEntity 表不会出现在我的 mySQL 数据库中 这里有什么帮助吗 下面是我的代码 持久
  • 关于等待超时错误的自定义消息

    我有时会使用 预期条件 功能量角器 1 7 中引入 Use case var EC protractor ExpectedConditions browser wait EC visibilityOf header displayName
  • Excel 2010 64 位无法创建 .net 对象

    我有一个在 Excel 中使用的简单类库 这是我的课程的简化 using System using System Runtime InteropServices namespace SimpleLibrary ComVisible true
  • 有什么方法可以暂停 firestore 侦听器而不删除它?

    有什么方法可以暂停 firestore 侦听器而不删除它 我有多个 Firebase 侦听器 其中一些侦听器依赖于其他侦听器 这些侦听器会在数据更改时更改或启动其他侦听器 假设我的第一个监听器启动了第二个监听器onSnapshot 第一个听
  • 重载指向两个不同类的指针的赋值运算符

    我的问题 我正在尝试重载指向两个不同类的指针的赋值运算符 这是一个例子 dc h ifndef DC H define DC H include ic h class dc double d char c public dc d 0 c 0
  • 一段时间后 AKFFTTap 停止生成数据

    我将 AudioKit 用于录音机应用程序 并向 AKMicrophone 添加了 AKFFTTap 以绘制自定义音频波形 这一切都运行良好 但是经过几次录音后 或者在应用程序录音屏幕打开一段时间后 FFT 数据突然变成全 0 我知道麦克风
  • 如何对出现在硬盘上的目录进行排序?

    在我的硬盘上 例如 目录1 目录2 目录3 目录4 我的代码是 DirectoryInfo dInfo new DirectoryInfo AutomaticsubDirectoryName DirectoryInfo subdirs dI
  • 如何在 Android Studio 中重新包含排除的目录?

    解释了如何在 Android Studio 中排除目录here 它还有一个关于不知道如何再次将其包含回来的警告 现在我需要这样做 当然 我可以再次创建 导入项目 但我想有更好的方法可以做到这一点 有没有 如何 由于没有 将目录标记为在 An
  • Python Selenium使用Windows浏览器上传文件

    我正在使用 selenium 在 Python 中开发一个浏览器自动化项目 我正在尝试将图片上传到页面 我登录 转到该页面 然后单击上传按钮 单击上传按钮后 将打开一个 Windows 文件浏览器 我必须在其中选择文件路径并单击 Windo
  • 如何使用c#以管理员身份运行批处理文件来安装Windows服务

    我创建了一个批处理文件 用于将我的程序安装为 Windows 服务 批处理文件的内容 gt C Project Test InstallUtil exe gt C Project Test ROServerService Server bi
  • 外部主机上的会话变得混乱

    问题听起来像这样 使用会话登录在我的本地主机上工作得很好 但是当完全相同的文件上传到我的主机 hostgator 时 会话不会 或者它们会变得混乱 此外 注销功能在主机上不起作用 我检查过 每个页面都有 session start 在里面
  • 使用 -v 查看调用?

    我的一个 iOS 应用程序遇到严重的链接器问题 请参阅上一篇文章详情 linker command failed with exit code 1 use v to see invocation 一个基本问题是 如何使用 v 查看调用 我可
  • 如何接收来自 Angular Reactive Form 的文件上传?

    我有在 Angular 7 反应式表单中上传文件的模块 我需要反应式表单 因为我需要一起上传文件和其他一些信息 我关注这篇文章 https medium com amcdnl file uploads with angular reacti
  • Scala 整数列表列表

    我是 Scala 新手 有点困惑 给定一个列表列表List List Int 如何调用每个列表的某个元素的特定索引 例如每个列表的第二个元素 Simple val ints List List 1 2 List 3 4 val result
  • 如何通过网络浏览器检查应用程序是否已安装?

    这是针对 Windows 的 我有一个要转换为 AIR 的 Flash 应用程序 我使用 NSIS 构建了一个强制安装程序 它运行良好 不过 我希望在网站上有一个图标 用于检查应用程序是否已安装并询问用户是否希望运行它 如果未安装 他们可以
  • 在 Windows/NTFS 中附加到文件是原子的吗?

    如果我从多个进程编写一个简单的文本日志文件 它们是否会覆盖 损坏彼此的条目 基本上 这个问题UNIX 中文件追加是原子的吗 但适用于 Windows NTFS 您可以在本地文件上获得原子追加 使用 FILE APPEND DATA 访问权限
  • 使用 OpenSSL 1.1.1d 静态编译 Qt 5.13.1 生成 QSslSocket::connectToHostEncrypted:TLS 初始化失败

    我想实现什么目标 我需要创建一个具有 SSL 支持的便携式 一体化 应用程序 问题是什么 因此 我面临的核心问题是将 SSL 支持纳入我的二进制 便携式应用程序中 A MCVE该应用程序的功能很简单 Project pro file QT