赞
踩
编译需要在linux环境下进行,笔者使用的是vmware虚拟机安装ubuntu 20.04进行编译,虚拟机的安装和ubuntu的安装这里就不详细说明了,可自行百度。
openssl编译需要提前安装所需要的环境,这一点在openssl官网文档中有说明。Android编译说明openssl/NOTES-ANDROID.md at master · openssl/openssl · GitHub,下面直接给出需要安装的环境
sudo apt update
sudo apt upgrade
sudo apt install make
sudo apt install build-essential
sudo apt install perl
在编译前还需要下载Android NDK和openssl,下载然后解压。
wget https://www.openssl.org/source/openssl-3.0.5.tar.gz
tar -zxvf openssl-3.0.5.tar.gz
wget https://dl.google.com/android/repository/android-ndk-r22b-linux-x86_64.zip
unzip android-ndk-r22b-linux-x86_64.zip
编译openssl,此前笔者使用的是DNK-r20b编译的,开始在Android Studio上使用的是DNK 21版本进行开发,打包没出现问题,但后面升级到NDK 22+后出现无法打包的情况。 根据提示编译需要添加 -fPIC ,在此记录一下。
export ANDROID_NDK_ROOT=/home/wgc/Android/android-ndk-r22b
PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
./Configure android-arm64 -D__ANDROID_API__=21 -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH}
make && make install
以上只是编译一个架构的静态库,如果需要其他架构还需重复编译,不够便捷,这里提供一个一键编译的版本。新建一个 build_openssl3.x.sh的文件,将以下内容复制到文件中,然后用命令执行 sh build_openssl3.x.sh即可。
#!/bin/bash -e sudo apt update sudo apt upgrade sudo apt install make sudo apt install build-essential sudo apt install perl #编译修改下面四个属性开始 OPENSSL_VERSION=3.0.5 #NDK23及以后下载和解压需要修改,注意下面注释掉的内容和说明 NDK_VERSION=android-ndk-r22b ANDROID_TARGET_API=21 #需要编译的架构 如果执行报数组错误 请使用 sudo dpkg-reconfigure dash 出现画面选择 否 ANDROID_ABI_ARRAY=(armeabi armeabi-v7a arm64-v8a x86 x86_64) #所有架构(armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64) #编译修改下面四个属性结束 WORK_PATH=$(cd "$(dirname "$0")";pwd) ANDROID_NDK_PATH=${WORK_PATH}/${NDK_VERSION} OPENSSL_SOURCES_PATH=${WORK_PATH}/openssl-${OPENSSL_VERSION} if [ ! -e openssl-${OPENSSL_VERSION}.tar.gz ] then echo "openssl 压缩包不存在" wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz fi if [ ! -d openssl-${OPENSSL_VERSION} ] then echo "openssl 目录不存在" tar -zxvf openssl-${OPENSSL_VERSION}.tar.gz fi if [ ! -e ${NDK_VERSION}-linux-x86_64.zip ] then echo "ndk 压缩包不存在" wget https://dl.google.com/android/repository/${NDK_VERSION}-linux-x86_64.zip #ndk23+后缀不区分x86_64 #wget https://dl.google.com/android/repository/${NDK_VERSION}-linux.zip fi if [ ! -d ${NDK_VERSION} ] then echo "ndk 目录不存在" unzip ${NDK_VERSION}-linux-x86_64.zip #ndk23+后缀不区分x86_64 #unzip ${NDK_VERSION}-linux.zip fi build_library() { mkdir -p ${OUTPUT_PATH} make && make install rm -rf ${OPENSSL_TMP_FOLDER} rm -rf ${OUTPUT_PATH}/bin rm -rf ${OUTPUT_PATH}/share rm -rf ${OUTPUT_PATH}/ssl rm -rf ${OUTPUT_PATH}/lib/engines* rm -rf ${OUTPUT_PATH}/lib/pkgconfig rm -rf ${OUTPUT_PATH}/lib/ossl-modules echo "Build completed! Check output libraries in ${OUTPUT_PATH}" } for ABI in ${ANDROID_ABI_ARRAY[@]} do ANDROID_TARGET_ABI=${ABI} #编译好的库输出路径 OUTPUT_PATH=${WORK_PATH}/openssl_${OPENSSL_VERSION}_${ANDROID_TARGET_ABI} OPENSSL_TMP_FOLDER=${WORK_PATH}/tmp/openssl_${ANDROID_TARGET_ABI} mkdir -p ${OPENSSL_TMP_FOLDER} cp -r ${OPENSSL_SOURCES_PATH}/* ${OPENSSL_TMP_FOLDER} echo "开始编译 ${ABI}" if [ "$ANDROID_TARGET_ABI" = "armeabi" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-arm -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "armeabi-v7a" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-arm -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "arm64-v8a" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-arm64 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "mips" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-mips -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "mips64" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-mips64 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "x86" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-x86 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library elif [ "$ANDROID_TARGET_ABI" = "x86_64" ] then export ANDROID_NDK_ROOT=${ANDROID_NDK_PATH} PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH cd ${OPENSSL_TMP_FOLDER} ./Configure android-x86_64 -D__ANDROID_API__=${ANDROID_TARGET_API} -static no-shared no-tests -fPIC --prefix=${OUTPUT_PATH} #NDK22及以上需要添加-fPIC build_library else echo "Unsupported target ABI: $ANDROID_TARGET_ABI" exit 1 fi done
编译后会出现以下文件夹,里面就是编译好的库文件和头文件
将头文件和库文件拷贝到项目中
链接静态库
cmake_minimum_required(VERSION 3.18.1) #隐藏符号表 add_definitions("-fvisibility=hidden") #指定c++文件路徑 file(GLOB SOURCE ${CMAKE_SOURCE_DIR}/*.cpp) include_directories(${CMAKE_SOURCE_DIR}) #添加目标库 add_library(openssl_test SHARED ${SOURCE}) #添加两个预编译库 add_library(openssl-crypto STATIC IMPORTED) set_target_properties(openssl-crypto PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/libcrypto.a) add_library(openssl-ssl STATIC IMPORTED) set_target_properties(openssl-ssl PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/libssl.a) #查找android log库 find_library(log-lib log) #编译关联目标库 target_link_libraries(openssl_test ${log-lib} openssl-ssl openssl-crypto)
实现Base64编码
/** * base64编码 * @param input 待编码内容 * @param length 待编码内容长度 * @param newLine 是否换行 * @return 编码后内容 */ char *base64Encode(const char *buffer, int length, bool newLine) { BIO *bmem = nullptr; BIO *b64 = nullptr; BUF_MEM *bptr; b64 = BIO_new(BIO_f_base64()); if (!newLine) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, buffer, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); BIO_set_close(b64, BIO_NOCLOSE); char *buff = (char *) malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = '\0'; BIO_free_all(b64); return buff; } /** * base64解码 * @param input 待解码内容 * @param length 待解码内容长度 * @param newLine 是否换行 * @return 解码后内容 */ char *base64Decode(const char *input, int length, bool newLine) { BIO *b64 = nullptr; BIO *bmem = nullptr; char *buffer = (char *) malloc(length); memset(buffer, 0, length); b64 = BIO_new(BIO_f_base64()); if (!newLine) { BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); } bmem = BIO_new_mem_buf(input, length); bmem = BIO_push(b64, bmem); BIO_read(bmem, buffer, length); BIO_free_all(bmem); return buffer; }
extern "C" {
JNIEXPORT jstring
Java_cn_wgc_myapplication_Openssl_base64Encode(JNIEnv * env , jobject instance, jstring content ) {
const char *content_ = env->GetStringUTFChars(content, nullptr);
char *encodeString = base64Encode(content_, strlen(content_), false);
LOGD("jniEncodeString :%s", encodeString) ;
return env -> NewStringUTF(encodeString);
}
}
val content = "123456789abcdefghijklmn"
val javaEncode = Base64.encodeToString(content.toByteArray(), Base64.NO_WRAP)
val opensslEncode = Openssl.instance.base64Encode(content)
执行完java与openssl编码的字符效果如下
参考链接:openssl_for_android/openssl_build.sh at master · 217heidai/openssl_for_android · GitHub
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。