【问题标题】:Qt for Android and BoringSSLQt for Android 和 BoringSSL
【发布时间】:2017-07-15 12:35:17
【问题描述】:

我正在为 Android 开发一个基于 Qt 的应用程序,它使用 QSslSocket 下载数据。由于自 Marshmallow Qt 程序依赖 OpenSSL 库以来 Android 从 OpenSSL 迁移到 BoringSSL,因此在 Android 6+ 上会产生以下警告:

W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 CRYPTO_free W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 EVP_CipherFinal W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 EVP_rc2_cbc W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 SSLv2_client_method W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 SSLv2_server_method W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 OPENSSL_add_all_algorithms_noconf W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 OPENSSL_add_all_algorithms_conf W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法解析 EC_get_builtin_curves W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法调用未解析的函数 OPENSSL_add_all_algorithms_conf W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法调用未解析的函数 EC_get_builtin_curves W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法调用未解析的函数 EC_get_builtin_curves W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: 无法设置 SSL_CTRL_SET_TLSEXT_HOSTNAME,服务器名称指示已禁用 W libtestopenssl.so: (null):0 ((null)): qt.network.ssl: QSslSocket: 无法调用未解析的函数 CRYPTO_free

但是,套接字本身成功连接到远程主机并从那里读取数据,没有任何明显的问题。这让我想知道是否需要自己构建 OpenSSL 库并将其打包,还是使用平台提供的 BoringSSL 就可以了。

我还注意到,Android 版本低于 6 的应用倾向于使用 OpenSSL 的系统版本,即使我提供了自己的版本。我尝试使用ANDROID_EXTRA_LIBS 添加构建的libssl.so 和libcrypto.so(从libssl.so.1.0.0 和libcrypto.so.1.0.0 重命名)(不确定是否也需要使用LIBS+=)甚至静态链接 libssl.a 和 libcrypto.a。仍然 QSslSocket::sslLibraryVersionString() 返回平台上可用的版本。

我的问题是:

  1. 是否需要自己构建OpenSSL库并打包或者使用平台提供的库?
  2. 如果我这样做了,如何让 Android 识别 libssl.so 和 libcrypto.so?

【问题讨论】:

  • 你有什么问题?
  • 首先需要自己搭建OpenSSL库并打包好还是使用平台提供的库好?如果我这样做了,如何让 Android 识别 libssl.so 和 libcrypto.so?
  • 您应该构建它们并随应用程序一起发布。较旧的 Android 使用与 1.0 不兼容的 openssl 0.9。不幸的是,android 并不那么容易,即使你发布了 openssl,它也会尝试先启动平台一。我现在有同样的问题,我认为唯一的解决办法是使用静态链接的 openssl 构建自己的 QT。

标签: android qt ssl openssl boringssl


【解决方案1】:

1. OpenSSL库需要自己搭建并打包还是使用平台提供的库就可以了?

  • 是的 - 您应该构建 OpenSSL 并将其打包。

https://developer.android.com/about/versions/nougat/android-7.0-changes.html

从 Android 7.0 开始,系统会阻止应用动态链接到非 NDK 库,这可能会导致您的应用崩溃。这种行为改变旨在跨平台更新和不同设备创建一致的应用体验。

  • 目前使用已安装的 BoringSSL 可能可行,但建议应用自带 OpenSSL 库。
  • 否则您的用户会看到弹出警告消息,并且该应用可能无法在更高版本的 Android 上运行。

为了减少此限制可能对当前发布的应用程序产生的影响,可以暂时访问一组使用量很大的库,例如 libandroid_runtime.so、libcutils.so、libcrypto.so 和 libssl.so在 Android 7.0(API 级别 24)上,针对 API 级别 23 或更低级别的应用。如果您的应用程序加载其中一个库,logcat 会生成一个警告,并且目标设备上会出现一个 toast 来通知您。如果您看到这些警告,则应更新您的应用程序以包含其自己的这些库副本或仅使用公共 NDK API。 Android 平台的未来版本可能会完全限制私有库的使用并导致您的应用程序崩溃。

2。如果我这样做了,如何让 Android 识别 libssl.so 和 libcrypto.so?

  • 我主要是按照此处概述的步骤成功的: http://doc.qt.io/qt-5/opensslsupport.html

  • 但请确保您获得了正确的版本:openssl-1.1.0f.tar.gz 似乎与 Qt 5.9 不兼容,并且我的应用程序没有加载库。

  • 为桌面编译并调用 QSslSocket::sslLibraryVersionString() 以查看 Qt 使用的 OpenSSL 版本。对我来说,它显示“OpenSSL 1.0.1t 2016 年 5 月 3 日”
  • 在 git repo 中标记“OpenSSL_1_0_1t”对我来说适用于 Qt 5.9.1
  • openssl.org 的 openssl-1.0.2l.tar.gz 也适用于 Qt 5.9.1

我使用 API 级别 19。一旦我使用 API 级别 23 或 25 进行测试,我将更新此答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多