当前位置:   article > 正文

Android openssl3.0.x编译和使用

android openssl

Android openssl3.0.x编译和使用

1、前提准备

编译需要在linux环境下进行,笔者使用的是vmware虚拟机安装ubuntu 20.04进行编译,虚拟机的安装和ubuntu的安装这里就不详细说明了,可自行百度。

vmware官网下载地址

ubuntu 20.04下载地址

2、编译环境

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
  • 1
  • 2
  • 3
  • 4
  • 5

3、开始编译

在编译前还需要下载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
  • 1
  • 2
  • 3
  • 4

编译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
  • 1
  • 2
  • 3
  • 4

4、一键编译

以上只是编译一个架构的静态库,如果需要其他架构还需重复编译,不够便捷,这里提供一个一键编译的版本。新建一个 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137

编译后会出现以下文件夹,里面就是编译好的库文件和头文件
在这里插入图片描述

5、使用

将头文件和库文件拷贝到项目中
在这里插入图片描述
链接静态库

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

实现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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
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);

}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
    val content = "123456789abcdefghijklmn"
    val javaEncode = Base64.encodeToString(content.toByteArray(), Base64.NO_WRAP)
    val opensslEncode = Openssl.instance.base64Encode(content)
  • 1
  • 2
  • 3

执行完java与openssl编码的字符效果如下
在这里插入图片描述
参考链接:openssl_for_android/openssl_build.sh at master · 217heidai/openssl_for_android · GitHub

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/198049?site
推荐阅读
相关标签
  

闽ICP备14008679号