【问题标题】:use libcryto.so and libssl.so in an android project?在 android 项目中使用 libcryto.so 和 libssl.so?
【发布时间】:2014-04-27 04:54:57
【问题描述】:

我是 Android NDK 的初学者。我想基于 openssl 库构建一个 RSA 示例。 首先,我在 Guardianproject 中使用 ndk-build 构建了 libssl.so 和 libcrypto.so 库。 接下来,我创建一个新的示例项目来集成库(libss.so 和 lybcryto.so)。我在这个post中遵循相同的@

我的应用目录

TrialApp
|
|-->Activity.java (includes System.LoadLibrary calls)
|
|-->jni
    |-->TestJNI2.cpp
    |
    |-->Android.mk
    |
    |-->includes
    |   |
    |   |-->openssl (dir containing *.h files)
    |
    |-->precompiled
       |-->libssl.so
       |-->libcrypto.so

我的 android.mk:

LOCAL_PATH := $(call my-dir)

# Prebuilt libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := precompiled/libssl.so
include $(PREBUILT_SHARED_LIBRARY)

# Prebuilt libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := precompiled/libcrypto.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

c_includes := $(LOCAL_PATH)
cf_includes := includes/openssl

cf_includes := $(addprefix -Ijni/,$(cf_includes))

export_c_includes := $(c_includes)

LOCAL_MODULE := security
LOCAL_SRC_FILES := TestJNI2.cpp
LOCAL_CFLAGS += $(cf_includes)
LOCAL_EXPORT_C_INCLUDES := $(export_c_includes)
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libssl.so
LOCAL_LDLIBS += $(LOCAL_PATH)/precompiled/libcrypto.so

include $(BUILD_SHARED_LIBRARY)

TestJNI2.cpp

/* OpenSSL headers */

#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

/* Initializing OpenSSL */

void init_openssl(void){
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
}

然后当我用 ndk-build 构建时总是有这样的问题

/data/workspace/TestJNI2/jni/TestJNI2.cpp:3:25: error: openssl/bio.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp:4:25: error: openssl/ssl.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp:5:25: error: openssl/err.h: No such file or directory
/data/workspace/TestJNI2/jni/TestJNI2.cpp: In function 'void init_openssl()':
/data/workspace/TestJNI2/jni/TestJNI2.cpp:10: error: 'SSL_load_error_strings' was not declared in this scope
/data/workspace/TestJNI2/jni/TestJNI2.cpp:11: error: 'ERR_load_BIO_strings' was not declared in this scope
/data/workspace/TestJNI2/jni/TestJNI2.cpp:12: error: 'OpenSSL_add_all_algorithms' was not declared in this scope
make: *** [/data/workspace/TestJNI2/obj/local/armeabi/objs/security/TestJNI2.o] Error 1

谁能帮帮我?或者如何基于 openssl lib 构建示例 RSA 算法?

【问题讨论】:

  • f_includes := includes/openssl 将其更改为 f_includes := includes。它找不到 openssl 目录,因为您已将其包含在内,因此它本质上是在寻找 includes/openssl/openssl/bio.h

标签: android android-ndk openssl java-native-interface


【解决方案1】:

我是 Android NDK 的初学者。我想基于 openssl 库构建一个 RSA 示例。

你可以,但你必须小心。这就是 Alex 告诉您在脚本中为 libssllibcrypto 使用静态库的原因。

主Android进程是zygote。就像 Linux 中的 init。 Zygote 在启动时会加载 OpenSSL,它会加载 0.9.8 版本。如果您链接到 OpenSSL 1.0.1,那么您将遇到神秘的运行时崩溃。崩溃是由于 Android 加载程序使用了 0.9.8 版本的库(已经从 Zygote 映射),而不是您的 OpenSSL 版本。

可以使用共享对象,但您的共享对象必须是 libssllibcrypto 的静态版本的包装器。

如果您使用 Android 的构建系统,那么您可以在 OpenSSL 的 wiki 上找到纯粹从命令行构建的其他说明。 wiki 页面包括设置环境和交叉编译。见FIPS Library and Android

另一件需要注意的事情:一定要使用-mfloat-abi=softfp 构建。股票 OpenSSL 在交叉编译时错过了这一点。您需要它来确保浮点数在堆栈上传递,并且 通过浮点寄存器。否则,您所有的浮点数都会神秘地具有 0.0f 值(就像在 RAND_add 中用于估计熵的浮点数一样)。

【讨论】:

    【解决方案2】:

    您应该在脚本中为 libssl 和 libcrypto 构建静态库。如果不能,请重命名这些库(您可以在构建后执行此操作,同时复制到您的 precompiled 目录)。原因是系统自带了这些共享库的自己(可能不同)版本,加载器将使用/system/lib/libssl.so/system/lib/libcrypto.so 而不是您的私有副本。

    关于Android.mk文件,我为你稍微清理了一下(注意我没有更改预建LOCAL_MODULE的名称,而是更改了LOCAL_MODULE 你最终构建了,因为security 太通用了,也可能恰好匹配某些设备上的系统库):

    LOCAL_PATH := $(call my-dir)
    
    # Prebuilt libssl
    include $(CLEAR_VARS)
    LOCAL_MODULE := ssl
    LOCAL_SRC_FILES := precompiled/libPrivateSsl.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    # Prebuilt libcrypto
    include $(CLEAR_VARS)
    LOCAL_MODULE := crypto
    LOCAL_SRC_FILES := precompiled/libPrivateCrypto.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := PrivateSecurity
    LOCAL_C_INCLUDES := includes
    LOCAL_SRC_FILES := TestJNI2.cpp
    LOCAL_LDLIBS := -llog
    LOCAL_SHARED_LIBRARIES := ssl crypto
    
    include $(BUILD_SHARED_LIBRARY)
    

    不要忘记你的 Java 应该首先加载依赖项:

    {
        System.loadLibrary("PrivateSsl");
        System.loadLibrary("PrivateCrypto");
        System.loadLibrary("PrivateSecurity");
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多