Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3016|回复: 2
打印 上一主题 下一主题

qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

[复制链接]

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
跳转到指定楼层
楼主
发表于 2020-5-5 13:48:29 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
找到相应动态库,放到.exe同级目录
一般位置
libeay32.dll ssleay32.dll
C:\Qt\Qt 5.xx.x\Tools\mingw730_32\opt\bin(32位)
C:\Qt\Qt 5.xx.x\Tools\mingw730_32\opt\bin(64位)
libcrypto-1_1.dll  libssl-1_1.dll

C:\Qt\Qt 5.xx.x\Tools\QtCreator\bin




回复

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
板凳
 楼主| 发表于 2020-5-5 13:50:37 | 只看该作者
https://www.cnblogs.com/qthub/p/12181347.html

使用Qt的https(get,post,put等)请求时报qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed错误。

开发环境
  • Windows10 64位
  • Qt 5.12.1
  • MSVC 2017编译器(版本:15.0)
发现问题
  • 在带开发环境的电脑上运行没问题,而移植到其他系统则有问题,报SSL错误,导致https请求不工作。
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed.问题分析
  • 根据打印的错误提示找到对应源码。
void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,                                        const QString &sslPeerName, OpenMode mode,                                        NetworkLayerProtocol protocol){    ...    if (!supportsSsl()) {        qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");        d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));        return;    }    d->init();    ...}
  • 如果supportsSsl函数返回false时打印错误(警告)信息,就不再执行后续操作了,于是继续查看supportsSsl函数。
/* 如果此平台支持SSL,则返回true;否则,返回false。 * 如果平台不支持SSL,套接字将失败在连接阶段。  */bool QSslSocket::supportsSsl(){    return QSslSocketPrivate::supportsSsl();}bool QSslSocketPrivate::supportsSsl(){    return ensureLibraryLoaded();}
  • ensureLibraryLoaded实现。
bool QSslSocketPrivate::ensureLibraryLoaded(){    if (!q_resolveOpenSslSymbols())        return false;    ...    return true;}
  • 由于Qt君使用的是windows系统所以选用loadOpenSslWin32加载SSL库函数。
bool q_resolveOpenSslSymbols(){    ...#ifdef Q_OS_WIN    QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();#else    QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();#endif    if (!libs.first || !libs.second)        // failed to load them        return false;    ...
  • loadOpenSslWin32实现。
static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32(){    ...#if QT_CONFIG(opensslv11)    // With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using    // MSVC and GCC, (-x64 suffix for 64-bit builds).#ifdef Q_PROCESSOR_X86_64#define QT_SSL_SUFFIX "-x64"#else // !Q_PROCESSOFR_X86_64#define QT_SSL_SUFFIX#endif // !Q_PROCESSOR_x86_64    tryToLoadOpenSslWin32Library(QLatin1String("libssl-1_1" QT_SSL_SUFFIX),                                 QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), pair);#undef QT_SSL_SUFFIX#else // QT_CONFIG(opensslv11)    // When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'.    // When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version)    // The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007)    if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) {        if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) {            if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) {                tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair);            }        }    }#endif // !QT_CONFIG(opensslv11)    return pair;}
  • Qt版本没有配置opensslv11,所以加载以下的SSL库操作。依次查找ssleay32和libeay32,如果没有找到就查找libssl-10和libcrypto-10依此类推直到libssl-7和libcrypto-7。
if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) {    if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) {        if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) {            tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair);        }    }}问题解决
  • 找对应平台版本的SSL库,Qt君将ssleay32和libeay32库放到运行目录下即解决了问题。
  • 由于开发环境存在ssleay32和libeay32路径链接,而打包程序又没有复制SSL库,导致移植到其他电脑的SSL功能不正常的问题。
一些总结
  • 可以将SSL库与应用程序一起部署,也可以在计算机上安装OpenSSL。
  • 根据不同的Qt版本SSL库可能有所不同。
  • Dependency Walker工具也找不到依赖的库,因为它是运行时加载的库。注:Dependency Walker可以扫描任何32位或64位Windows模块exe,dll,ocx,sys等,并构建所有对象的层次结构树图。

  • SSL库Windows版本下载地址:
https://slproweb.com/products/Win32OpenSSL.html
  • SSL源码地址:
https://github.com/openssl/openssl
  • 如果是mingw版本的SSL库,可在下列路径找到(是你实际的路径):
C:\Qt\Qt5.12.1\Tools\mingw730_64\opt\bin

开发日常 | 解决SSL缺库导致https失败的问题

回复 支持 反对

使用道具 举报

1272

主题

2067

帖子

7958

积分

认证用户组

Rank: 5Rank: 5

积分
7958
沙发
 楼主| 发表于 2020-5-5 13:48:49 | 只看该作者
https://www.cnblogs.com/fancyop/p/qt_ssl_q.html
在使用QML的时候运行程序的时候遇到了好几次类似以下问题:
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

qt.network.ssl: QSslSocket: cannot resolve DTLSv1_2_server_method
qt.network.ssl: QSslSocket: cannot resolve DTLSv1_2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_CTX_new
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_CTX_free
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_CTX_set_ssl_ctx
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_CTX_set_flags
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_CTX_finish
qt.network.ssl: QSslSocket: cannot resolve SSL_CONF_cmd
qt.network.ssl: QSslSocket: cannot resolve SSL_set_alpn_protos
qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_alpn_select_cb
qt.network.ssl: QSslSocket: cannot resolve SSL_get0_alpn_selected
qt.network.ssl: QSslSocket: cannot resolve DTLS_server_method
qt.network.ssl: QSslSocket: cannot resolve DTLS_client_method
qt.network.ssl: QSslSocket: cannot call unresolved function DTLS_client_method
————————————————————————————————————————————————

重点来了:最后总结了一下大概可以从以下方法解决:

1、对于Qt mingw版本用户来说
一般在:

C:\Qt\Qt 5.xx.x\Tools\mingw730_32\opt\bin(32位)

或者:

C:\Qt\Qt 5.xx.x\Tools\mingw730_32\opt\bin(64位)

目录(以实际安装路径为准)可以找到  libeay32.dll ssleay32.dll 两个文件

  1)复制这两个文件到Qt工程生成可执行文件的目录(即exe文件同目录下)中去,再次运行,错误消失

  2)复制这两个文件到C:\Qt\Qt 5.xx.x\Qt 5.xx.x\mingwxxx_xx\bin 的目录下,再次运行,错误消失

  可以参考这篇文章:&#128073; (Qt-network.ssl问题报错)



上方式一般对于mingw版本来说基本可以解决

2、对于Qt MSVC版本用户来说
  A、可以随便一个Qt C++工程中打印出openssl版本信息

#include <QSslSocket>
qDebug()<<QSslSocket::sslLibraryBuildVersionString();


5.12.3版本为例,执行打印出  OpenSSL 1.1.1b 26 Feb 2019

  B、根据相应版本去下载OpenSSL的二进制文件,当然也可以选择自己编译,只不过有点麻烦

文件下载地址:http://slproweb.com/products/Win32OpenSSL.html

我下载的是Win64 OpenSSL v1.1.1d Light,完了之后安装


  C、安装好后在安装目录找到 libcrypto-1_1-x64.dll libssl-1_1-x64.dll 两个文件 ,然后粘贴到

  C:\Qt\Qt5.13.0\5.13.0\msvc2017_64\bin目录再次运行,错误消失,完美解决
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-23 03:18 , Processed in 0.060596 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表