在Android应用中为HttpClient更改OpenSSL库
我需要在我的项目中为HttpClient使用自定义OpenSSL库。
我为Android编译了libcrypto.so和libssl.so ,并将文件放在jniLibs文件夹中。 应用Heartbleed扫描仪看到它们。 System.loadLibrary("crypto")
和System.loadLibrary("ssl")
有效。 但现在我需要让HttpClient使用我的库而不是标准的SSL库。 但我不知道哪种方式可以移动以及如何移动。
我使用的是OpenSSL 1.0.1h和Android Studio 1.0.2。
提前感谢您的建议。
我为Android编译了libcrypto.so和libssl.so,并将文件放在jniLibs文件夹中……
这不行。
Android使用OpenSSL 1.0.0并在/system
。 Zygote在启动时启动并加载低级版本的OpenSSL(它类似于init
– 所有Android进程都是从它分叉的)。
当您的进程从Zygote分叉时,您的1.0.1版本永远不会加载,因为已经从Zygote加载了1.0.0。 你永远不会知道有问题,因为低级版本提供了你需要的所有符号(它的二进制兼容)。
您需要编写包装器共享对象。 包装器共享对象必须链接到OpenSSL 1.0.1的静态版本( libcrypto.a
和libssl.a
)。 您的包装器必须导出唯一的符号,例如My_OpenSSL_add_all_algorithms
和My_SSL_load_error_strings
。 在内部,您的共享对象可以引用未修饰的名称, OpenSSL_add_all_algorithms
和SSL_load_error_strings
。
所以你的共享对象看起来是这样的(另见GCC的Visibility页面 ):
#if __GNUC__ >= 4 #define DLL_PUBLIC __attribute__ ((visibility ("default"))) #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) #else #define DLL_PUBLIC #define DLL_LOCAL #endif DLL_PUBLIC void My_OpenSSL_add_all_algorithms() { return (void)OpenSSL_add_all_algorithms(); } DLL_PUBLIC void My_SSL_load_error_strings() { return (void)SSL_load_error_strings(); } ...
然后,使用-fvisibility=hidden
标志进行编译,并链接libcrypto.a
和libssl.a
。 只有标有DLL_PUBLIC
的函数才能通过JNI导出和调用。
我认为不需要#if __GNUC__ >= 4
,因为Android提供的交叉编译工具是GCC 4.0以上。 事实上,我认为它目前是GCC 4.8。
在Android应用中为HttpClient更改OpenSSL库
这个问题更难了。 在共享包装器中提供更新的OpenSSL之后,我不知道如何让Android的HttpClient
使用它。
更糟糕的情况回答:你可能需要派Android并提供更新的OpenSSL。
一个可能更好的解决方案:删除HttpClient
代码,将其放在您自己的包中,然后确保源代码的端口使用共享对象。