QT + OpenSSL + Android
QT + OpenSSL + Android
我想设置OpenSSL库。我的Qt项目。在Linux下,它可以很好地与内置的OpenSSL一起工作。我把这个添加到我的。pro文件中:
LIBS+=-lcrypto
PKGCONFIG += openssl
但如果我在Android中使用它,它会给出错误。我按照下面的说明做了:
$ . ./setenv-android.sh
$ cd openssl-1.0.1h/
$ perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
$ ./config shared -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine --openssldir=/usr/local/ssl/$ANDROID_API
$ make depend
$ ./Configure shared android-armv7
$ make build_libs
$ export CC=/home/laci/android-ndk-r10/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
$ export AR=/home/laci/android-ndk-r10/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar
$ export ANDROID_DEV=/home/laci/android-ndk-r10/platforms/android-14/arch-arm/usr/
$ make all
$ sudo -E make install CC=$ANDROID_TOOLCHAIN/arm-linux-androideabi-gcc RANLIB=$ANDROID_TOOLCHAIN/arm-linux-androideabi-ranlib
这些网站是我的资料来源:
- OpenSSL wiki
- QtDoc -添加OpenSSL支持
我做错了什么?
提前感谢您的回答
解决方案是:
1a)正确的方法:为android编译openssl库(使用1.0.2+,不要使用1.1)。* -至少对于Qt 5.9.2)
或
1b)快速和肮脏的方式:从任何现有的应用程序APK(警告:过时的库==>安全威胁)获取它们,如果你需要快速和肮脏的解决方案。查找libssl。还有libcrypto。所以在APK arm目录下。
然后2a)打开Qt Creator, Projects -> [project] -> Build &运行-> Android for armeabi->v7a ->构建->构建Android APK -> Android ->附加库->添加…(添加libssl。所以,libcrypto。所以)
或
2b)在你的.pro makefile中添加以下内容:
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
ANDROID_EXTRA_LIBS =
$$PWD/android/libs/arm/libcrypto.so
$$PWD/android/libs/arm/libssl.so
}
($ $ PWD/android/. .是您在项目中放置这些库的路径)。ANDROID_PACKAGE_SOURCE_DIR在这种情况下看起来是可选的。
然后3)添加它们加载到AndroidManifest(至少对Qt 5.9.2有效):小心地将它们添加到您现有的主活动和进程外服务的元数据中,如果有的话。
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --:lib/libssl.so:lib/libcrypto.so"/>
"lib"在这里必须是"lib",它指的是设备上的目录布局,而不是你的项目结构。
然后4)构建你的apk。检查您的库是否在适当的位置:
$ jar tvf ./android-build/build/outputs/apk/android-build-debug.apk| grep libssl
344388 Tue Apr 11 12:35:36 EEST 2017 lib/armeabi-v7a/libssl.so
我把这个指令放在这里,因为我花了太多时间寻找答案,任何没有ANDROID_EXTRA_LIBS的东西都不能为我工作。
注
为什么有这么大的问题?因为6.0以下的Android可能包含自己的libssl/libcrypto,通过"-l"链接会在你的主二进制文件中添加自动加载条目(不是qt管理的),系统库可能是错误的版本,或者静默加载而不是你的附带二进制文件,从而掩盖Android 7的bug。Android 7绝对不包含libssl, "-l"将失败,并且在运行时无法解析符号。
通过不使用"-l"和使用Qt的"android.app."相反,您将强制QtLoader使用您的libs版本。请记住,openssl 1.0.2与默认的android Qt构建和1.1一起工作。由于符号不同,*将不起作用。(SSL_init_library是1.0.2,OPENSSL_init_library是1.1.*)
有趣的是,由于这些复杂性,方法"1b)"可能不起作用。您选择的APK可能包含libssl。但是它的作者没有正确地构建和加载它,所以他的libssl。所以可能是不正确的版本的共享库,这在android上通常是不允许的,但作者使用-l并且从不加载自己的库(使用system代替),并且从不知道他的库不会在android上加载
填词+ = -lcrypto
我看到两个潜在的问题。首先,您可能需要LIBS += -lssl -lcrypto
。
/usr/lib
中使用i386或x86_64),而不是目标的OpenSSL(即,在/usr/local/ssl/android/lib '中使用libssl
和libcrypto
)。要解决这个问题,我发现最简单的方法是指定库的完整路径:
LIBS += /usr/local/ssl/android/lib/libssl.a /usr/local/ssl/android/lib/libcrypto.a
您必须避免只使用-lssl -lcrypto
,如果可用,它链接到共享对象。Android使用OpenSSL 0.9.8。所以你将在编译时编译1.0.1h,但在运行时链接android 0.9.8。这会导致一堆无法解释的错误。
这种行为的发生是因为Android的主进程- Zygote -在启动后加载了0.9.8版本的OpenSSL。在Zygote分叉进入您的进程后,0.9.8已经加载。他们的操作系统将不会加载你的1.0.1版本,因为链接依赖已经满足了。
我想总结一下解决方案(这是我的主观意见):
- 仅支持openssl 0.9.8za
- 必须添加libcrypto。(thankx @jww)
我的setv -android.sh "可编辑"变量:
_ANDROID_NDK="android-ndk-r10"
_ANDROID_EABI="arm-linux-androideabi-4.8"
_ANDROID_ARCH=arch-arm
_ANDROID_API="android-14"
建筑过程:
$ . ./setenv-android.sh
$ tar xzf openssl-0.9.8za.tar.gz
$ cd openssl-0.9.8za/
$ ./config
$ make
。支持文件:
# FORMS, SOURCES, TARGET, etc...
unix:!macx: LIBS += -L$$PWD/../SSL/openssl-0.9.8za/ -lcrypto
INCLUDEPATH += $$PWD/../SSL/openssl-0.9.8za/include
DEPENDPATH += $$PWD/../SSL/openssl-0.9.8za/include
unix:!macx: PRE_TARGETDEPS += $$PWD/../SSL/openssl-0.9.8za/libcrypto.a
对我有用的是:编辑openssl Makefile。共享并替换
-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
-soname=$$SHLIB
这样库的内部名称被更改为libcrypto。还有libssl。而不是libcrypto。So .1.0.0
清理并重新编译openssl和你的应用。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用ndk-build.cmd构建Android.so文件
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 如何在openssl-ecc中获取十六进制格式的私钥
- Android NDK传感器向事件队列报告奇怪的间隔
- LINK 尝试使用 OpenSSL evp aes 256 c++ 时出错
- 如何在OpenSSL中从configuration.h.in获取configuration.h
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- OpenSSL TLS服务器-使用客户端证书白名单
- OpenCV Android C++ imwrite not found
- Android NDK 编译 LAME HAVE_MPGLIB > 'interface.h' 文件未找到
- 通过 Openssl 命令行加密,通过 c++ 解密
- 如何使用 Boost Asio 在 Android 上获取我的本地 udp IP 地址?
- 使用已使用 java 编码的 openssl 解码数据
- Android Studio 中带有静态库的原生C++代码
- Android CMake: Could NOT find OpenSSL
- 在Android上编译OpenSSL
- 如何存储和加载 cacerts.pem for gSoap-OpenSSL Android 应用程序
- QT + OpenSSL + Android
- Android NDK linking OpenSSL