use libcryto.so and libssl.so in an android project?

15,188

Solution 1

You should build static libraries for libssl and libcrypto in your script. If you can't, rename these libraries (you can do this after build, while copying to your precompiled directory). The reason is that the system comes with its own (probably different) version of these shared libraries, and the loader will use /system/lib/libssl.so and /system/lib/libcrypto.so instead of your private copies.

Regarding the Android.mk file, I slightly cleaned it up for you (note that I did not change the names of prebuilt LOCAL_MODULEs, but changed the name of LOCAL_MODULE you finally build, because security is, well, too generic and could also happen to match a system library on some device):

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)

Don't forget that your Java should load the dependencies first:

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

Solution 2

I'm beginer to Android NDK. I want to build a RSA example base on openssl libary.

You can, but you have to be careful. Here's the reason Alex told you to use static libraries for libssl and libcrypto in your script.

The master Android process is zygote. Its like init in Linux. Zygote loads OpenSSL when its start, and it loads version 0.9.8. If you link against OpenSSL 1.0.1, then you will get mysterious runtime crashes. The crashes are due to the Android loader using the 0.9.8 version of the library (already mapped from Zygote), and not your version of OpenSSL.

You can use a shared object, but your shared object must be a wrapper around the static version of libssl and libcrypto.

If you are not using Android's build system, then you can find additional instructions for building purely from the command line at OpenSSL's wiki. The wiki page includes setting the envrionment and cross compiling. See FIPS Library and Android.

Another thing to watch out for: be sure to build with -mfloat-abi=softfp. The stock OpenSSL misses that when cross compiling. You need it to ensure floats are passed on the stack, and not through floating point registers. Otherwise, all your floats will mysteriously have 0.0f value (like the floats used to estimate entropy in RAND_add).

Share:
15,188
tuan.giao
Author by

tuan.giao

Updated on June 10, 2022

Comments

  • tuan.giao
    tuan.giao almost 2 years

    I'm beginer to Android NDK. I want to build a RSA example base on openssl libary. First, I built libssl.so and libcrypto.so librairies with ndk-build in the guardianproject. Next, I create a new sample project to integrate libary (libss.so & lybcryto.so). I follow the same in this post

    My App directory

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

    My 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();
    }
    

    Then when i build with ndk-build always have problems like this

    /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
    

    Can anyone help me? Or how to build an example RSA algorthim base on openssl lib?