OpenSSL
是一個(gè)強(qiáng)大的開源安全套接字層密碼庫水评,它包含了主要的密碼學(xué)算法癌幕,常用的密鑰和證書封裝管理以及SSL協(xié)議,并提供豐富的應(yīng)用程序供測(cè)試或其他目的使用匆浙。
在Android
上開發(fā)對(duì)于安全的需求越來越高员寇,雖然OpenSSL
出現(xiàn)過幾次漏洞弄慰,但它仍然是在安全方面的使用最多的加密庫之一。
OpenSSL
是一個(gè)基于c語言開發(fā)的蝶锋,古老的陆爽,開源的加密庫,想要在Android
上使用OpenSSL
必須要借助NDK
,先使用NDK編譯成Android上面的動(dòng)態(tài)連接庫(或者靜態(tài)鏈接庫)扳缕,再借助JNI層的封裝慌闭,提供給Java層調(diào)用。
這篇文章主要寫的是如何編譯Android
的OpenSSL
類庫躯舔。參考OpenSSL的官方文檔:https://wiki.openssl.org/index.php/Android
前期準(zhǔn)備
環(huán)境準(zhǔn)備:
- 編譯環(huán)境為MacOS
- OpenSSL的源代碼
- Setenv-android.sh 構(gòu)建腳本
- 安裝Make
- 安裝makedepend
OpenSSL
可以在github上找到源代碼,源代碼地址:https://github.com/openssl/openssl
git clone git@github.com:openssl/openssl.git
也可以在官網(wǎng)上下載最新的release版本:https://www.openssl.org/source/
由于OpenSSL
項(xiàng)目的主干(master)上提交的是開發(fā)分支贡必,最好把OpenSSL
切換到最新的release版本上面
git checkout OpenSSL_1_1_0e
Setenv-android.sh
是用來編譯Android上的OpenSSL的腳本,下載地址:https://wiki.openssl.org/images/7/70/Setenv-android.sh
給Setenv-android.sh
腳本可以運(yùn)行的權(quán)限
chmod a+x Setenv-android.sh
安裝makedepend
brew install makedepend
運(yùn)行腳本
Setenv-android.sh
腳本的作用是用來給編譯OpenSSL配置Android編譯的環(huán)境變量的庸毫。腳本下載完成之后是不能直接運(yùn)行仔拟,原因在于腳本里面的變量并沒有配置,需要配置變量:
ANDROID_NDK_ROOT:
ANDROID_ARCH: arch-arm
ANDROID_EABI: arm-linux-androideabi-4.9
ANDROID_API: android-23
ANDROID_SYSROOT: /platforms/android-23/arch-arm
ANDROID_TOOLCHAIN:
FIPS_SIG:
CROSS_COMPILE: arm-linux-androideabi-
ANDROID_DEV: /platforms/android-23/arch-arm/usr
已經(jīng)設(shè)置了Android NDK
和Android SDK
變量的飒赃,只需要把正確的值配置到腳本就可以了,設(shè)置腳本中的變量:
ANDROID_NDK_ROOT=$NDK_HOME
_ANDROID_API="android-23"
_ANDROID_EABI="arm-linux-androideabi-4.9"
運(yùn)行腳本:
./Setenv-android.sh
沒有Error
出現(xiàn)就表示配置正確了利花。
編譯OpenSSL
上面的配置已經(jīng)給OpenSSl的編譯環(huán)境設(shè)置了環(huán)境變量例如:
export MACHINE=armv7
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=arm
根據(jù)上面的設(shè)置的環(huán)境變量,再運(yùn)行./config
就可以實(shí)現(xiàn)編譯Android上OpenSSL的配置,make就可以開始編譯了载佳。
因?yàn)樵贏ndroid設(shè)備上面運(yùn)行炒事,建議不要編譯完整的OpenSSL庫,官方給的建議編譯Android的選項(xiàng):
shared,no-ssl2,no-ssl3,no-comp,no-hw,no-engine
編輯OpenSSl
的類庫可以安裝到本地蔫慧,這樣可以像使用NDK中其他庫一樣的使用OpenSSL挠乳,編譯命令可以設(shè)置--openssldir
用來指定OpenSSL的安裝目錄。
cd openssl-1.0.1t
perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=/usr/local/ssl/$ANDROID_API
運(yùn)行到這里的時(shí)候得到一個(gè)這樣的信息:
perating system: i686-apple-darwinDarwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64
WARNING! If you wish to build 64-bit library, then you have to
invoke './Configure darwin64-x86_64-cc' *manually*.
You have about 5 seconds to press Ctrl-C to abort.
編譯的OpenSSL
使用的是本地的darwin64-x86_64-cc
,并不是想要的arm-linux-androideabi-gcc
編譯的,編譯的這個(gè)類庫是不能在Android上面使用的睡扬。原因是什么呢盟蚣?查看了下環(huán)境變量:
echo $ANDROID_API
發(fā)現(xiàn)這個(gè)變量沒有配置,上面的環(huán)境變量的配置Setenv-android.sh
在設(shè)置的環(huán)境變量并沒有起作用卖怜。
優(yōu)化編譯腳本
在Setenv-android.sh
中屎开,嘗試下打印$ANROID_API
的值,打印$ANDROID_API
的內(nèi)容:
echo "ANDROID_API:
echo $ANDROID_API
"
得到結(jié)果為:
...
ANDROID_API: android-23
...
可以看到$ANDROID_API
變量在Setenv-android.sh
的生命周期內(nèi)是有效的马靠,而腳本運(yùn)行結(jié)束之后設(shè)置的變量沒有設(shè)置成功這個(gè)應(yīng)該是因?yàn)槲沂褂昧?code>fish有關(guān),因此我就考慮把編譯的命令都放在Setenv-adnroid.sh
里奄抽,在Setenv-android.sh
的生命周期內(nèi)運(yùn)行完所有的編譯命令。
重新建一個(gè)腳本名字為build-android-openssl.sh
復(fù)制配置好的Setenv-android.sh
的內(nèi)容到build-android-openssl.sh
,再添加命令:
cd openssl
make clean
perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=/usr/local/ssl/$ANDROID_API
make depend
make all
sudo -E make install CC=$ANDROID_TOOLCHAIN/arm-linux-androideabi-gcc RANLIB=$ANDROID_TOOLCHAIN/arm-linux-androideabi-ranlib
注:該腳本和openssl
源碼的目錄是同一級(jí)目錄甩鳄。
完成編譯之后可以看到/usr/local/ssl/android-23
有生成了對(duì)應(yīng)的庫和文件,OpenSSL源代碼目錄下生成了:libcrypto.so
和libcrypto.a
這樣就完成了Android的OpenSSL
庫編譯完成峦树,下一步就可以嘗試在NDK中引用OpenSSL了册踩。
優(yōu)化后的腳本地址:https://github.com/jjz/script/blob/master/build_android_openssl.sh