错误“无法加载SSL库";在Android上使用TidHTTP [英] Error "Could not load SSL library" on Android with TidHTTP

查看:227
本文介绍了错误“无法加载SSL库";在Android上使用TidHTTP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用TIdHTTP下载文件.在Delphi Seattle中获取.这是一个适用于android的应用程序,我所有的尝试都失败了.我所得到的都是相同的错误无法加载SSL库".步骤如下:

I'm trying to download a file with TIdHTTP.Get in Delphi Seattle. It's an app for android and all my attempts fails. All i get it's the same error "Could not load SSL library". This is the procedure:

procedure TfrmMain.DownloadPicture(const AURL: string);
var
  MeS: TMemoryStream;
  cidSSL: TIdSSLIOHandlerSocketOpenSSL;
  cidHTTP: TIdHTTP;
begin
  cidHTTP:= TIdHTTP.Create(nil);
  cidSSL:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  Mes := TMemoryStream.Create;

  try
    cidHTTP.ReadTimeout := 30000;
    cidHTTP.IOHandler := IdSSL;
    cidSSL.SSLOptions.Method := sslvSSLv3;
    cidSSL.SSLOptions.Mode := sslmUnassigned;
    cidSSL.StartSSL;
    cidHTTP.Get(AURL, Mes);
  except
    on E : Exception do
      begin showmessage('Error: '+E.Message);
      end;
  end;
  Mes.Position := 0;
  frmImage.Image.Bitmap.LoadFromStream(Mes);
end;

推荐答案

如果您使用Android 6棉花糖,则OpenSSL在Android上应该可以正常工作.当出现无法加载"错误时,可以在IdSSLOpenSSLHeaders单元中调用Indy的WhichFailedToLoad()函数,以找出为什么无法加载OpenSSL的原因.如果您的设备未预安装OpenSSL,则可以在应用程序中部署OpenSSL二进制文件,并使用Indy的IdOpenSSLSetLibPath()函数告诉Indy从何处加载它们.

If you are NOT using Android 6 Marshmallow, OpenSSL should be working fine on Android. When you get the "could not load" error, you can call Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit to find out why OpenSSL could not be loaded. If your device does not have OpenSSL pre-installed, you can deploy the OpenSSL binaries with your app, and use Indy's IdOpenSSLSetLibPath() function to tell Indy where to load them from.

话虽如此,从Android 6棉花糖开始, Google不再支持OpenSSL (在Android上).它已被名为 BoringSSL 的自定义派生代替,其中

That being said, starting with Android 6 Marshmallow, Google no longer supports OpenSSL on Android. It has been replaced with a custom fork named BoringSSL, which Indy does not fully support yet (although some BoringSSL-related changes have been made to Indy after Seattle's release). So, if you are having trouble with using Indy SSL/TLS on Android 6, you can try upgrading to the latest SVN snapshot to see if it helps (at the time of this writing, the current SVN revision is 5359).

BoringSSL对OpenSSL API接口进行了一些主要更改(删除函数,更改数据类型等),因此它与现有的OpenSSL代码不向后兼容.但更糟糕的是,BoringSSL使用与OpenSSL相同的库文件名,并在设备启动时预加载,因此无法在您的Android应用程序中部署自定义的OpenSSL库二进制文件.当应用尝试在运行时加载OpenSSL库文件名时,Android将仅使用预加载的BoringSSL二进制文件(无论您是否调用Indy的IdOpenSSLSetLibPath()函数).

BoringSSL makes some major changes to the OpenSSL API interface (dropping functions, changing data types, etc), so it is not backwards-compatible with existing OpenSSL code. But to make matters worse, BoringSSL uses the same library filenames as OpenSSL, and is pre-loaded at device startup, so it is not possible to deploy custom-built OpenSSL library binaries with your Android app. Android will simply use the pre-loaded BoringSSL binaries when the app tries to load the OpenSSL library filenames at runtime (regardless of whether you call Indy's IdOpenSSLSetLibPath() function).

Indy在Android的NDK级别(而不是Java级别)上运行,因此要使Indy避免使用BoringSSL,需要用户选择以下任一条件:

Indy operates at the NDK level of Android, not the Java level, so to make Indy avoid BoringSSL would require users to either:

  1. 使用与BoringSSL不冲突的新文件名重新编译OpenSSL库(AFAIK没有可用的已知版本),然后更新Indy以使用这些文件名.

  1. recompile the OpenSSL libraries with new filenames that don't conflict with BoringSSL (AFAIK no known version of this is available), and then update Indy to use those filenames.

将OpenSSL源代码直接编译到其Android应用中.目前尚未将Indy设置为在iOS以外的任何平台上都不支持OpenSSL的静态链接,但是如果有人可以在Android上为OpenSSL生成可行的.a文件,则这应该是对Indy的IdSSLOpenSSLHeaders_static单元进行相关定义的微小更改. .我确实知道至少有一个用户尝试过此路由,但该用户尚未成功(获取源代码以正确完全链接时出错).

compile the OpenSSL source code directly into their Android app. Indy is not currently setup to support static-linking of OpenSSL on any platform other than iOS, but this should be a minor change to update Indy's IdSSLOpenSSLHeaders_static unit with the relevant definitions if someone can produce viable .a files for OpenSSL on Android. I do know of at least one user attempting this route, but that user has not had success yet (errors getting the source code to fully link correctly).

切换到Android的基于Java的更高级别的加密API.这是Google的首选解决方案.但是Indy目前不支持它.为此,需要使用JNI调用访问Java API,为Android套接字I/O和SSL/TLS编写一组全新的TIdStackTIdIOHandler类.但这存在性能和线程问题,需要解决.

switch to Android's higher-level Java-based crypto APIs. This is Google's preferred solution. But Indy does not support it at this time. Doing so would require writing a whole new set of TIdStack and TIdIOHandler classes for Android socket I/O and SSL/TLS, using JNI calls to access the Java APIs. But this has performance and threading issues that need to be dealt with.

因此,目前尚没有已知可行的解决方法来使Indy SSL/TLS在Android 6+上运行.

So, there is no known viable workaround available at this time to make Indy SSL/TLS work on Android 6+.

更新:Embarcadero论坛中的用户能够找到与Indy兼容并可以在Android 6上运行的OpenSSL .so文件:

Update: a user in the Embarcadero forums was able to find OpenSSL .so files that are compatible with Indy and work on Android 6:

https://forums.embarcadero.com/thread.jspa?threadID=211089

在我的应用程序崩溃的许多报告(如果安装在Android 6设备上)之后,我在网上搜索了一些技巧,并找到了一些需要的.so编译文件(1.02版),将这两个文件添加到我的应用程序的Play商店部署中(资产\内部)并更改了Indy的调用路径

After many reports of my apps crashing if installed in Android 6 devices I've searched the net for some tips and the couple of needed .so compiled files, 1.02 version, added the two files to the play store deployment of my apps (assets\internal) and changed the Indy's path calling

IdOpenSSLSetLibPath(TPath.GetDocumentsPath)

IdOpenSSLSetLibPath(TPath.GetDocumentsPath)

在我的数据模块的OnCreate中.

in the OnCreate of my datamodule.

对代码进行修改后,我的应用程序可以在带有Android 6.0.1的全新S7以及所有其他最近的Android设备(使用Play商店部署进行测试)上完美运行.

After those modifications of my code my Apps run perfectly on my brand new S7 with Android 6.0.1, and on all the other recent Android devices (tested using the Play Store deployment).

现在Google弹出警告,告诉我与我的应用程序一起部署的OpsnSSL文件不是最低要求的1.02f版本(或1.01r)....因此,我在此论坛中发帖.

And now the Google warning pops up telling me that the OpsnSSL files deployed with my apps are not of the minimum required 1.02f version (or 1.01r).... and so my post in this forum.

...

无论如何,您都可以在这里下载最新的.so文件,这是我目前部署的文件: https://drive.google.com/file/d/0B7AxqW32K0oXWW9nUk9qaFpHT0k/view ?usp =分享

Anyway you can download here the latest .so files, the ones that I deploy at this moment: https://drive.google.com/file/d/0B7AxqW32K0oXWW9nUk9qaFpHT0k/view?usp=sharing

同一讨论中的另一位用户似乎也取得了一些成功:

Another user in the same discussion also seems to have some success as well:

我已经在android 6上运行,加载.so库好几个月了.新的问题是我们需要编译openssl库的新版本. Cygwin无法为我正确编译,因此即时通讯切换到Linux安装程序来创建它们(如果可能)这里是一个存储库,您可以获取一些当前的预构建库 https://github. com/emileb/OpenSSL-for-Android-Prebuilt.git

heres a repository you can grab some current prebuilt ones https://github.com/emileb/OpenSSL-for-Android-Prebuilt.git


更新:以下(德语)论坛讨论为注册用户提供了适用于Android(和iOS模拟器)的OpenSSL 1.0.2g二进制文件.它们不会在Google Play商店中显示安全警告:


Update: The following (German) forum discussion provides OpenSSL 1.0.2g binaries for Android (and iOS Simulator) to registered users. They do not display the security warning in the Google Play store:

http://www.delphipraxis.net/188736- kompilierte-openssl-bibliotheken-fuer-android.html

OpenSSL 1.0 .2g Android.zip

OpenSSL 1.0.2g iOS Simulator.zip

更新:现在可在Embarcadero附件论坛中获得适用于OpenSSL 1.0.2g的Android二进制文件:

Update: the Android binaries for OpenSSL 1.0.2g are now available in the Embarcadero Attachments forum:

https://forums.embarcadero.com/thread.jspa?threadID=211147

然后,要加载OpenSSL而不是BoringSSL,请按照以下步骤操作:

Then, to load OpenSSL instead of BoringSSL, follow these steps:

  1. 将2个.so文件添加到项目部署中,并将其设置为部署到.\assets\internal\文件夹

  1. Add the 2 .so files to your project deployment and set them to deploy to the .\assets\internal\ folder

System.StartupCopy单元添加为DPR的uses子句中的第一个单元.

add the System.StartupCopy unit as the first unit in your DPR's uses clause.

在应用启动时调用IdOpenSSLSetLibPath(TPath.GetDocumentsPath).


更新:Embarcadero附件论坛中现已包含OpenSSL 1.0.1t和1.0.2h二进制文件:


Update: OpenSSL 1.0.1t and 1.0.2h binaries are now in the Embarcadero Attachments forum:

https://forums.embarcadero.com/thread.jspa?threadID=211147

更新:这些二进制文件现已发布在Indy的Fulgan镜子上:

Update: the binaries have now been posted on Indy's Fulgan mirror:

http://indy.fulgan.com/SSL/

这篇关于错误“无法加载SSL库";在Android上使用TidHTTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆