为什么在Debian Stretch上,QsslSocket可以在Qt 5.3上工作,但不能在Qt 5.7上工作?

33

我有一个应用程序,使用 QWebSocket 类,但不使用 SSL。当我执行使用 Qt 5.3 编译的版本时,它能正常工作,但是在执行 Qt 5.7 可执行文件时会出现以下警告并冻结:

QSslSocket: cannot resolve CRYPTO_num_locks
QSslSocket: cannot resolve CRYPTO_set_id_callback
QSslSocket: cannot resolve CRYPTO_set_locking_callback
QSslSocket: cannot resolve ERR_free_strings
QSslSocket: cannot resolve EVP_CIPHER_CTX_cleanup
QSslSocket: cannot resolve EVP_CIPHER_CTX_init
QSslSocket: cannot resolve sk_new_null
QSslSocket: cannot resolve sk_push
QSslSocket: cannot resolve sk_free
QSslSocket: cannot resolve sk_num
QSslSocket: cannot resolve sk_pop_free
QSslSocket: cannot resolve sk_value
QSslSocket: cannot resolve SSL_library_init
QSslSocket: cannot resolve SSL_load_error_strings
QSslSocket: cannot resolve SSL_get_ex_new_index
QSslSocket: cannot resolve SSLv2_client_method
QSslSocket: cannot resolve SSLv3_client_method
QSslSocket: cannot resolve SSLv23_client_method
QSslSocket: cannot resolve SSLv2_server_method
QSslSocket: cannot resolve SSLv3_server_method
QSslSocket: cannot resolve SSLv23_server_method
QSslSocket: cannot resolve X509_STORE_CTX_get_chain
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf
QSslSocket: cannot resolve SSLeay
QSslSocket: cannot resolve SSLeay_version
QSslSocket: cannot call unresolved function CRYPTO_num_locks
QSslSocket: cannot call unresolved function CRYPTO_set_id_callback
QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function sk_num

在我使用的5.3版本中未看到这些警告(该版本正常工作),这表明我不应忽略它们,就像这个问题所要求的那样。此外,QT += network 已经在我的src.pro文件中了.

我曾经认为Debian已将这些符号从openssl包中删除。有人能告诉我这里发生了什么以及我该如何解决吗?

系统信息

我正在运行Debian stretch。

$ uname -r
4.8.0-2-amd64

我已经安装了openssl和libssl-dev

openssl is already the newest version (1.1.0c-2). 
libssl-dev is already the newest version (1.1.0c-2).

我尝试过使用Qt 5.3和5.7运行此程序。

$ qmake -v
QMake version 3.0
Using Qt version 5.7.1 in /usr/lib/x86_64-linux-gnu

我也遇到了同样的问题,一直卡在这里...还在继续搜索...以下是更多关于此问题的信息:
  • 在我的Debian Stretch上,所有Qt版本(Qt5.3、5.6、5.7、5.8)都会出现此问题。对于我的同事来说,Qt5.3可以正常工作。因此,可能是由于安装Qt版本的方式不同,而不是Qt版本本身引起的。
  • 它只发生在WebSocket客户端,而不是WebSocket服务器。
- Fylhan
8个回答

46

简短概述:

Debian Stretch版本自带OpenSSL 1.1; Qt需要使用OpenSSL 1.0,因此需要为Qt提供所需支持。

apt install libssl1.0-dev

详细回答

从这个 关于 OpenSSL 和 Qt 的回答中,我找到了一个提示,并使用以下方法显示了用于编译时和运行时的 SSL 库版本:

qDebug()<<"SSL version use for build: "<<QSslSocket::sslLibraryBuildVersionString();
qDebug()<<"SSL version use for run-time: "<<QSslSocket::sslLibraryVersionNumber();
qDebug()<<QCoreApplication::libraryPaths();

然后它会显示:

SSL version use for build:  "OpenSSL 1.0.1e-fips 11 Feb 2013"
... lot of SSL warnings...
SSL version use for run-time:  0
("/opt/Qt/5.8/gcc_64/plugins", "/home/Project/..../build...Desktop_Qt_5_8_0_GCC_64bit-Release/src/release/build_linux_64")

但是Debian Stretch是搭载了OpenSSL 1.1的。正如预料的那样,有关这个问题的所有网页线程都是真实的:这是一个OpenSSL库版本兼容性问题。

我使用“apt install libssl1.0-dev”命令解决了这个问题。我仍然有两个关于SSLv3的SSL警告,但至少这只是一个警告(我在网上读到过一些关于它的东西,现在找不到了)。

SSL version use for build:  "OpenSSL 1.0.1e-fips 11 Feb 2013"
QSslSocket: cannot resolve SSLv3_client_method
QSslSocket: cannot resolve SSLv3_server_method
SSL version use for run-time:  268443839
("/opt/Qt/5.8/gcc_64/plugins", "/home/Project/..../build...Desktop_Qt_5_8_0_GCC_64bit-Release/src/release/build_linux_64")

摘要

在Qt支持OpenSSL 1.1之前,你可以选择以下方法之一:

  1. 安装OpenSSL 1.0(在Debian中可能可行)
  2. 编译并安装OpenSSL 1.0(我没有测试过,但应该与1.相同)
  3. 将OpenSSL 1.0与你的Qt应用一起打包(我没有测试过,但应该与1.相同)
  4. 使用"-openssl-linked"选项重新编译Qt(根据这个答案,我没有进行测试,也不想测试)

2
亲爱的7hibault,你的评论应该被接受作为答案,你救了我整整一周!谢谢! - Hirbod
那些 qDebug 行是让我在 Windows 上解决 DLL Hell 并找出 Qt 构建时使用的 OpenSSL 版本的诀窍。具体来说,QSslSocket::sslLibraryBuildVersionString() 就是答案。 - Phlucious
更新:自Qt5.10起支持OpenSSL 1.1,但您必须使用适当的配置重新构建它(请参见forum.qt.io/topic/103139/openssl-1-1-1-support/3)。自Qt 5.12.4起默认集成(https://blog.qt.io/blog/2019/06/17/qt-5-12-4-released-support-openssl-1-1-1/)。 - Arnaud M.

7

我在一个Debian Stretch服务器上遇到了同样的问题。通过7hibaults的评论,我解决了这个问题。

运行以下命令对我有用:

sudo apt-get install libssl1.0-dev

4
我在 Ubuntu 16.04 上遇到了以下错误:E: 包 'libssl1.0-dev' 没有安装候选项。 - KoviNET
@KoviNET:我也遇到了同样的错误。如果您已经解决了它,请分享一下您是如何解决的。 - Atul

5

如果你使用的是Ubuntu18.04+,你可以使用这个内置的工具,它也适用于更新的版本。

sudo apt-add-repository -y ppa:rael-gc/rvm
sudo apt-get update
sudo apt-get install libssl1.0-dev 

谢谢!这是安装Qt旧版本所必需的步骤,从他们的存档中下载: https://download.qt.io/new_archive/qt/ 在Ubuntu 20.04.3 LTS上。我需要获取Qt 5.5.1,但.run文件无法运行,直到我安装了这个版本的libssl1.0-dev。 - JimmyJimJames
1
这在Ubuntu 22.04 Jammy上运行成功。 - karianpour

3

Fylhan's answer在Debian Buster下不起作用,因为libssl1.0-dev是一个过渡包,不再受支持。

Qt网站上有一个错误报告,从Giuseppe d'Angelo的评论中得知以下解决方法:

解决方法1

如果你的发行版有一个OpenSSL 1.0目录,并且带有正确的符号链接(例如Arch有/usr/lib/openssl-1.0/libssl.so),请使用LD_LIBRARY_PATH强制搜索该目录。

解决方法2

创建自己的带有符号链接的目录,并使用LD_LIBRARY_PATH。

解决方法3

重新构建自己的Qt。

我使用第二种方法解决了问题,在我的情况下详细说明如下:

  1. mkdir openssl1.0 ; cd openssl1.0
  2. cp /usr/lib/x86_64-linux-gnu/libssl.so.1.0.2 libssl.so.1.0.2
  3. ln -s libssl.so.1.0.2 libssl.so
  4. 在 QtCreator 中,选择 Projects > Desktop Qt 5.8.0 > Build > Build Environment > 添加:变量 LD_LIBRARY_PATH,值为 /path/to/dir/openssl1.0(或者在控制台中的命令前加入 LD_LIBRARY_PATH="/path/to/dir/openssl1.0"

你可能还需要用同样的方法设置libcrypto.so,但这对我来说已经足够了。此解决方案可避免更改整个系统的符号链接。


2
如果您使用的是Debian 11(bullseye),并且无法安装libssl1.0-dev,请执行以下操作:
添加以下两个源:
echo "deb http://deb.debian.org/debian/ stretch main contrib non-free" >> /etc/apt/sources.list.d/source.list 
echo "deb-src http://deb.debian.org/debian stretch main contrib non-free" >> /etc/apt/sources.list.d/source.list

然后运行apt-get update

最后运行apt install libssl1.0-dev

这里是源代码,了解更多信息。


1

我在Ubuntu 16.04上使用Qt 5.11.1遇到了问题。

我通过运行以下命令获取了Qt所使用的ssl版本:

qDebug()<<"SSL version use for build: "<<QSslSocket::sslLibraryBuildVersionString();

哪种打印方式

构建时使用的SSL版本: "OpenSSL 1.0.2k-fips 26 Jan 2017"

我通过从这里获取的openssl-1.0.2k解决了问题 http://www.linuxfromscratch.org/blfs/view/8.0/postlfs/openssl.html

然后运行以下命令进行构建

./config --prefix=./usr --openssldir=./etc/ssl  --libdir=lib   shared   zlib-dynamic
make

成功完成后,我在当前目录下获得了以下库的构建

path/openssl-1.0.2k/libssl.so.1.0.0
path/openssl-1.0.2k/libssl.so
path/openssl-1.0.2k/libcrypto.so.1.0.0
path/openssl-1.0.2k/libcrypto.so 

请打开QtCreator,进入Projects > Desktop Qt 5.11.1 GCC 64bit > Build > Build Environment > Add :添加变量LD_LIBRARY_PATH,值为path/openssl-1.0.2k。在我的情况下,LD_LIBRARY_PATH已经存在一些值,所以我进行了编辑,像这样::/home/user/Qt5.11.1/Tools/QtCreator/lib/Qt/lib::path/openssl-1.0.2k
上述步骤解决了Ubuntu 16.04上Qt5.11.1的ssl警告问题。

0

您需要使用以下命令安装以下软件包以解决问题:

sudo apt install libssl1.0-dev

-1

你需要将 /usr/lib/x86_64-linux-gnu 中的符号链接更改为:

libcrypto.solibcrypto.so.1.0.2
libssl.solibssl.so.1.0.2

而不是:

libcrypto.solibcrypto.so.1.1
libssl.solibssl.so.1.1


据我所知,在 /usr/lib 中更改符号链接是不推荐的。首先,更改将应用于整个系统(某些其他组件肯定依赖于 libssl1.0.2 并且不支持 1.1),并且在更新时(例如安全更新到 libssl1.0.3)会自动而隐式地更改。 - Fylhan
是的,但直到今天你有更多的选择。 - blackmoon
我不同意。我的答案中至少有四个选项。而且这还不是穷尽所有可能的情况。 - Fylhan
新版本的库已经删除/弃用了很多函数,因此链接到它将无法解决任何问题,因为在启动应用程序时,这些函数仍然无法找到! - mBardos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接