OpenSSL是一個強大的開源的安全套接字層密碼庫,包含了主要的密碼學演算法,常用的金鑰和證照封裝管理以及SSL協議。
Android上的開發對於安全的需求越來越高,雖然OpenSSL出現過幾次漏洞,但OpenSSL仍然是在安全方便的使用最多的加密庫。
OpenSSL是一個基於c開發的,古老的,開源的加密庫,想在Android上使用OpenSSL必須要藉助NDK,使用NDK編譯成Android上面的動態連線庫(或者靜態連結庫),再借助JNI層的封裝,提供給Java層呼叫。
這篇文章主要寫的是如何構建Android的OpenSSL類庫。參考OpenSSL的官方文件:https://wiki.openssl.org/index.php/Android
前期準備
- OpenSSL的原始碼
- setenv-adnroid.sh 構建指令碼
- Make
OpenSSL已經託管在github上了,原始碼地址:https://github.com/openssl/openssl
git clone git@github.com:openssl/openssl.git
也可以在官網上下載最新的release版本:https://www.openssl.org/source/
由於OpenSSL專案的主幹(master)上提交的是dev版本,最好把OpenSSL切換到最新的release版本上面
git checkout OpenSSL_1_0_1t
setenv-android.sh指令碼地址:https://wiki.openssl.org/images/7/70/Setenv-android.sh
給指令碼可以執行的許可權
chmod a+x Setenv-android.sh
安裝makedepend
brew install makedepend
執行指令碼
指令碼下載完成之後是不能直接執行的,原因在於指令碼里面的變數並沒有配置,需要配置的變數:
1 2 3 4 5 6 7 8 9 |
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 |
電腦中已經設定了Android NDK和SDK變數的,只需要把正確的值配置到指令碼就可以了,設定指令碼中的變數:
1 2 3 |
ANDROID_NDK_ROOT=$NDK_HOME _ANDROID_API="android-23" _ANDROID_EABI="arm-linux-androideabi-4.9" |
執行指令碼:
./Setenv-android.sh
沒有Error
出現就是配置正確了。
編譯OpenSSL
上面的配置會設定成環境變數。例如:
1 2 3 4 |
export MACHINE=armv7 export RELEASE=2.6.37 export SYSTEM=android export ARCH=arm |
根據上面的設定的環境變數,再執行./config
就可以實現編譯Android上library的配置,然後在make就可以了。
因為在Android裝置上面執行,建議不要編譯完整的OpenSSL庫,官方給的建議選項:shared,no-ssl2,no-ssl3,no-comp,no-hw,no-engine.
OpenSSl的庫需要安裝到本地的電腦中,這樣可以像使用NDK庫一樣的使用OpenSSL,編譯命令可以設定--openssldir
用來指定OpenSSL的安裝目錄。
1 2 3 |
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 |
執行到這裡的時候得到一個這樣的資訊:
1 2 3 4 |
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是我的PC上的版本darwin64-x86_64-cc
,並不是想要的Android版本。
檢視下環境變數:
echo $ANDROID_API
發現這個變數沒有配置成功,上面的環境變數的配置(Setenv-android.sh)在我的電腦上面並沒有起作用。
優化指令碼
根據OpenSSL在wiki中提到的指令碼(Setenv-android.sh),嘗試下列印$ANROID_API
的值。
在指令碼里面更新列印內容:
echo “ANDROID_API:
echo $ANDROID_API
“
得到結果:
1 2 3 |
... ANDROID_API: android-23 ... |
可以看到變數的配置在Setenv-android.sh
的生命週期內是有效的,因此我可以把編譯的命令都放在Setenv-adnroid.sh
中,在Setenv-android.sh
的生命週期內執行完編譯命令。
重新建一個指令碼名字為build-android-openssl.sh
複製配置好的Setenv-android.sh
的內容到build-android-openssl.sh
,再新增命令:
1 2 3 4 5 6 7 8 |
cd openssl-1.0.1t 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 |
可以看到/usr/local/ssl/android-23
有生成了對應的庫和檔案。
OpenSSL原始碼目錄下生成了:libcrypto.so
和libcrypto.a
Android的OpenSSL庫編譯完成,下一步就可以嘗試在NDK中引用OpenSSL了。
優化後的指令碼地址:https://github.com/jjz/script/blob/master/build-android-openssl.sh