如果你
没有
使用Android 6 Marshmallow,OpenSSL在Android上应该是工作正常的。 当你遇到 "无法加载 "的错误时,你可以在
IdSSLOpenSSLHeaders
单元中调用Indy的
WhichFailedToLoad()
函数,以找出OpenSSL无法加载的原因。 如果你的设备没有预装OpenSSL,你可以将OpenSSL二进制文件与你的应用程序一起部署,并使用Indy的
IdOpenSSLSetLibPath()
函数来告诉Indy从哪里加载它们。
也就是说,从Android 6 Marshmallow开始,
谷歌不再支持
Android上的
OpenSSL
。它已经被一个名为
BoringSSL
的自定义分叉所取代,
Indy还不完全支持
它(尽管在西雅图发布后,Indy已经做了
一些
与BoringSSL相关的修改)。 因此,如果你在Android 6上使用Indy SSL/TLS时遇到问题,你可以尝试升级到最新的
Github快照
,看看是否有帮助。
BoringSSL对OpenSSL的API接口做了一些
重大
改变(放弃了函数,改变了数据类型,等等),所以它与现有的OpenSSL代码不具备向后兼容性。 但更糟糕的是,BoringSSL使用与OpenSSL相同的库文件名,并在设备启动时预装,所以不可能在你的Android应用中部署自定义的OpenSSL库二进制文件。当应用程序试图在运行时加载OpenSSL库文件名时,Android将简单地使用预加载的BoringSSL二进制文件(无论你是否调用Indy的
IdOpenSSLSetLibPath()
函数)。
Indy在Android的NDK层面上操作,而不是在Java层面上,所以要让Indy避免使用BoringSSL,就要求用户要么。
用新的文件名重新编译OpenSSL库,使其不与BoringSSL冲突(AFAIK没有这个版本),然后更新Indy以使用这些文件名。
将OpenSSL的源代码直接编译到他们的Android应用中。Indy目前的设置并不支持在iOS以外的任何平台上静态链接OpenSSL,但如果有人能够为Android上的OpenSSL制作可行的
.a
文件,这应该是一个很小的改变,用相关的定义更新Indy的
IdSSLOpenSSLHeaders_static
单元。我确实知道至少有一个用户在尝试这条路线,但该用户还没有成功(让源代码完全正确链接的错误)。
切换到安卓的更高级别的基于Java的加密API。 这是谷歌的首选解决方案。 但印地安人目前并不支持它。 这样做需要为Android套接字I/O和SSL/TLS编写一套全新的
TIdStack
和
TIdIOHandler
类,使用JNI调用来访问Java APIs。 但这有性能和线程问题需要处理。
所以,目前还没有已知的可行的解决方法来使Indy SSL/TLS在Android 6+上工作。
更新
:Embarcadero论坛上的一位用户能够找到与Indy兼容的OpenSSL
.so
文件,并能在Android 6上工作。
https://forums.embarcadero.com/thread.jspa?threadID=211089
在许多关于我的应用程序安装在安卓6设备上会崩溃的报告之后,我在网上搜索了一些提示和几个需要的.so编译文件,1.02版本,将这两个文件添加到我的应用程序的play store部署中(assets\internal),并改变了Indy的路径,调用
IdOpenSSLSetLibPath(TPath.GetDocumentsPath)
在我的数据模块的OnCreate中。
在对我的代码进行这些修改后,我的应用程序在我的全新的S7上完美运行,采用的是Android 6.0.1,在所有其他最近的Android设备上也是如此(使用Play Store部署测试)。
而现在,谷歌警告弹出,告诉我与我的应用程序一起部署的OpsnSSL文件不是最低要求的1.02f版本(或1.01r)....,所以我在这个论坛的帖子。
总之,你可以在这里下载最新的.so文件,也就是我现在部署的文件。
https://drive.google.com/file/d/0B7AxqW32K0oXWW9nUk9qaFpHT0k/view?usp=sharing
同一讨论中的另一个用户似乎也有一些成功。
我已经在安卓6上运行了几个月,加载.so库很正常。新的问题是我们需要编译新版本的openssl库。Cygwin对我来说不能正常编译,所以我改用linux安装来创建它们(如果可能的话)
https://wiki.openssl.org/index.php/Android#Build_the_OpenSSL_Library_2
这里有一个资源库,你可以抓取一些当前的预建库
https://github.com/emileb/OpenSSL-for-Android-Prebuilt.git
更新
:以下(德国)论坛的讨论为注册用户提供了Android(和iOS模拟器)的OpenSSL 1.0.2g二进制文件。它们在Google Play商店中不显示安全警告。
http://www.delphipraxis.net/188736-kompilierte-openssl-bibliotheken-fuer-android.html
OpenSSL 1.0.2g Android.zip
OpenSSL 1.0.2g iOS Simulator.zip
更新
:OpenSSL 1.0.2g的Android二进制文件现在可以在Embarcadero Attachments论坛上找到。
https://forums.embarcadero.com/thread.jspa?threadID=211147
然后,为了加载OpenSSL而不是BoringSSL,请遵循以下步骤。
将2个
.so
文件添加到你的项目部署中,并将它们设置为部署到
.\assets\internal\
文件夹中
在你的DPR的
uses
条款中添加
System.StartupCopy
单元作为第一个单元。
在应用程序启动时调用
IdOpenSSLSetLibPath(TPath.GetDocumentsPath)
。
更新
。OpenSSL 1.0.1t和1.0.2h二进制文件现在在Embarcadero附件论坛上。
https://forums.embarcadero.com/thread.jspa?threadID=211147
更新
:二进制文件现在已经发布在Indy的Fulgan镜像上。
http://indy.fulgan.com/SSL/
更新
:Indy不再使用Fulgan镜像来托管OpenSSL二进制文件。它们现在在他们自己的GitHub repo中。
https://www.indyproject.org/2020/06/16/openssl-binaries-moved-to-github/
https://github.com/IndySockets/OpenSSL-Binaries