SQLCipherとは
- SQLCipherはSQLiteの暗号化を提供するライブラリ
- 通常のSQLiteのAPIをそのまま使用して使えるのでセキュアなアプリを作る際によく利用される
Android15の16KBページサイズとは
- デバイスのメモリ管理単位が従来の4KBから16KBに拡大された
- より大規模なメモリ操作を効率的に行えるようになり、特にメモリを大量に消費するアプリのパフォーマンス向上が見込める
SQLCipherの対応要否
- 16KBページサイズに対応したネイティブバイナリ(.a, .so)か確認する
- MavenCentralからaarファイルをダウンロードし、格納されている.soファイルを確認する
# aarのダウンロード
$ curl -L https://repo1.maven.org/maven2/net/zetetic/sqlcipher-android/4.6.0/sqlcipher-android-4.6.0.aar -o sqlcipher-android-4.6.0.aar
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 9537k 100 9537k 0 0 6857k 0 0:00:01 0:00:01 --:--:-- 6856k
# aarの解凍
$ unzip sqlcipher-android-4.6.0.aar -d sqlcipher-android-4.6.0
Archive: sqlcipher-android-4.6.0.aar
inflating: sqlcipher-android-4.6.0/R.txt
inflating: sqlcipher-android-4.6.0/AndroidManifest.xml
inflating: sqlcipher-android-4.6.0/classes.jar
inflating: sqlcipher-android-4.6.0/proguard.txt
creating: sqlcipher-android-4.6.0/res/
creating: sqlcipher-android-4.6.0/res/values/
inflating: sqlcipher-android-4.6.0/res/values/values.xml
inflating: sqlcipher-android-4.6.0/META-INF/com/android/build/gradle/aar-metadata.properties
creating: sqlcipher-android-4.6.0/jni/
creating: sqlcipher-android-4.6.0/jni/arm64-v8a/
inflating: sqlcipher-android-4.6.0/jni/arm64-v8a/libsqlcipher.so
creating: sqlcipher-android-4.6.0/jni/armeabi-v7a/
inflating: sqlcipher-android-4.6.0/jni/armeabi-v7a/libsqlcipher.so
creating: sqlcipher-android-4.6.0/jni/x86/
inflating: sqlcipher-android-4.6.0/jni/x86/libsqlcipher.so
creating: sqlcipher-android-4.6.0/jni/x86_64/
inflating: sqlcipher-android-4.6.0/jni/x86_64/libsqlcipher.so
# .soが2**14(16KB)にアラインされているか確認
$ ~/Library/Android/sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p arm64-v8a/libsqlcipher.so | grep LOAD
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
LOAD off 0x0000000000523410 vaddr 0x0000000000524410 paddr 0x0000000000524410 align 2**12
LOAD off 0x000000000057f218 vaddr 0x0000000000581218 paddr 0x0000000000581218 align 2**12
$ ~/Library/Android/sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p armeabi-v7a/libsqlcipher.so | grep LOAD
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
LOAD off 0x003a48e0 vaddr 0x003a58e0 paddr 0x003a58e0 align 2**12
LOAD off 0x003d4f40 vaddr 0x003d6f40 paddr 0x003d6f40 align 2**12
$ ~/Library/Android/sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p x86/libsqlcipher.so | grep LOAD
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
LOAD off 0x004effc0 vaddr 0x004f0fc0 paddr 0x004f0fc0 align 2**12
LOAD off 0x005214cc vaddr 0x005234cc paddr 0x005234cc align 2**12
$ ~/Library/Android/sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p x86_64/libsqlcipher.so | grep LOAD
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
LOAD off 0x00000000005ac960 vaddr 0x00000000005ad960 paddr 0x00000000005ad960 align 2**12
LOAD off 0x000000000060b660 vaddr 0x000000000060d660 paddr 0x000000000060d660 align 2**12
# apkをビルドしてチェック
$ sh check_elf_alignment.sh app/build/outputs/apk/release/app-release.apk
Recursively analyzing app/build/outputs/apk/release/app-release.apk
=== APK zip-alignment ===
1405124 lib/arm64-v8a/libsqlcipher.so (OK - compressed)
8376834 lib/x86_64/libsqlcipher.so (OK - compressed)
Verification succesful
=========================
=== ELF alignment ===
-e /var/folders/XXX/T/app-release_out_XXXXX.HU6CvFjaoM/lib/armeabi-v7a/libsqlcipher.so: UNALIGNED (2**12)
-e /var/folders/XXX/T/app-release_out_XXXXX.HU6CvFjaoM/lib/x86/libsqlcipher.so: UNALIGNED (2**12)
-e /var/folders/XXX/T/app-release_out_XXXXX.HU6CvFjaoM/lib/arm64-v8a/libsqlcipher.so: UNALIGNED (2**12)
-e /var/folders/XXX/T/app-release_out_XXXXX.HU6CvFjaoM/lib/x86_64/libsqlcipher.so: UNALIGNED (2**12)
-e \e[31mFound 4 unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).
=====================
check_elf_alignment.sh
check_elf_alignment.sh
#!/bin/bash
progname="${0##*/}"
progname="${progname%.sh}"
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
cleanup_trap() {
if [ -n "${tmp}" -a -d "${tmp}" ]; then
rm -rf ${tmp}
fi
exit $1
}
usage() {
echo "Host side script to check the ELF alignment of shared libraries."
echo "Shared libraries are reported ALIGNED when their ELF regions are"
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
echo
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
}
if [ ${#} -ne 1 ]; then
usage
exit
fi
case ${1} in
--help | -h | -\?)
usage
exit
;;
*)
dir="${1}"
;;
esac
if ! [ -f "${dir}" -o -d "${dir}" ]; then
echo "Invalid file: ${dir}" >&2
exit 1
fi
if [[ "${dir}" == *.apk ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
echo "=== APK zip-alignment ==="
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
echo "========================="
else
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
echo " You can install the latest build-tools by running the below command"
echo " and updating your \$PATH:"
echo
echo " sdkmanager \"build-tools;35.0.0-rc3\""
fi
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
dir="${tmp}"
fi
if [[ "${dir}" == *.apex ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
dir="${tmp}"
fi
RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"
unaligned_libs=()
echo
echo "=== ELF alignment ==="
matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do
# We could recursively call this script or rewrite it to though.
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
[[ $(file "${match}") == *"ELF"* ]] || continue
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
unaligned_libs+=("${match}")
fi
done
if [ ${#unaligned_libs[@]} -gt 0 ]; then
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
elif [ -n "${dir_filename}" ]; then
echo -e "ELF Verification Successful"
fi
echo "====================="
確認に使用するコマンドの詳細はAndroid Developersにまとめられている
以下対応忘備録
Git Clone
- SQLCipherのandroid向けartifactは2種類公開されている
artifact | GitHub |
---|---|
net.zetetic:android-database-sqlcipher |
|
net.zetetic:sqlcipher-android |
-
net.zetetic:sqlcipher-android
は後継であり、これからアプリにSQLCipherを組み込む場合は基本的にこちらを使う - 今回の対応も
net.zetetic:sqlcipher-android
を使う
SQLCipher for Androidのビルド準備
- SQLCipher for Androidのビルドには2つの外部プロジェクトのビルド生成物とOpenSSLのincludeディレクトリ配下のファイルが必要
- OpenSSLを使ってビルドした
libcrypto.a
- OpenSSLの
include
ディレクトリ配下のファイル群(crypto
,internal
,openssl
) - SQLCipher本体をビルドして作成した
sqlite3.c
,sqlite3.h
OpenSSLのビルド
- sqlcipher/android-database-sqlcipherにそれっぽいスクリプトがあるので参考にする
build-openssl-libraries.sh
build-openssl-libraries.sh
#! /usr/bin/env bash
MINIMUM_ANDROID_SDK_VERSION=$1
MINIMUM_ANDROID_64_BIT_SDK_VERSION=$2
OPENSSL_DIR=$3
ANDROID_LIB_ROOT=$4
(cd ${OPENSSL_DIR};
if [[ ! ${MINIMUM_ANDROID_SDK_VERSION} ]]; then
echo "MINIMUM_ANDROID_SDK_VERSION was not provided, include and rerun"
exit 1
fi
if [[ ! ${MINIMUM_ANDROID_64_BIT_SDK_VERSION} ]]; then
echo "MINIMUM_ANDROID_64_BIT_SDK_VERSION was not provided, include and rerun"
exit 1
fi
if [[ ! ${ANDROID_NDK_HOME} ]]; then
echo "ANDROID_NDK_HOME environment variable not set, set and rerun"
exit 1
fi
HOST_INFO=`uname -a`
case ${HOST_INFO} in
Darwin*)
TOOLCHAIN_SYSTEM=darwin-x86_64
;;
Linux*)
if [[ "${HOST_INFO}" == *i686* ]]
then
TOOLCHAIN_SYSTEM=linux-x86
else
TOOLCHAIN_SYSTEM=linux-x86_64
fi
;;
*)
echo "Toolchain unknown for host system"
exit 1
;;
esac
NDK_TOOLCHAIN_VERSION=4.9
OPENSSL_CONFIGURE_OPTIONS="-fPIC -fstack-protector-all no-idea no-camellia \
no-seed no-bf no-cast no-rc2 no-rc4 no-rc5 no-md2 \
no-md4 no-ecdh no-sock no-ssl3 \
no-dsa no-dh no-ec no-ecdsa no-tls1 \
no-rfc3779 no-whirlpool no-srp \
no-mdc2 no-ecdh no-engine \
no-srtp"
rm -rf ${ANDROID_LIB_ROOT}
for SQLCIPHER_TARGET_PLATFORM in armeabi-v7a x86 x86_64 arm64-v8a
do
echo "Building libcrypto.a for ${SQLCIPHER_TARGET_PLATFORM}"
case "${SQLCIPHER_TARGET_PLATFORM}" in
armeabi-v7a)
CONFIGURE_ARCH="android-arm -march=armv7-a"
ANDROID_API_VERSION=${MINIMUM_ANDROID_SDK_VERSION}
OFFSET_BITS=32
;;
x86)
CONFIGURE_ARCH=android-x86
ANDROID_API_VERSION=${MINIMUM_ANDROID_SDK_VERSION}
OFFSET_BITS=32
;;
x86_64)
CONFIGURE_ARCH=android64-x86_64
ANDROID_API_VERSION=${MINIMUM_ANDROID_64_BIT_SDK_VERSION}
OFFSET_BITS=64
;;
arm64-v8a)
CONFIGURE_ARCH=android-arm64
ANDROID_API_VERSION=${MINIMUM_ANDROID_64_BIT_SDK_VERSION}
OFFSET_BITS=64
;;
*)
echo "Unsupported build platform:${SQLCIPHER_TARGET_PLATFORM}"
exit 1
esac
TOOLCHAIN_BIN_PATH=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/${TOOLCHAIN_SYSTEM}/bin
PATH=${TOOLCHAIN_BIN_PATH}:${PATH} \
./Configure ${CONFIGURE_ARCH} \
-D__ANDROID_API__=${ANDROID_API_VERSION} \
-D_FILE_OFFSET_BITS=${OFFSET_BITS} \
${OPENSSL_CONFIGURE_OPTIONS}
if [[ $? -ne 0 ]]; then
echo "Error executing:./Configure ${CONFIGURE_ARCH} ${OPENSSL_CONFIGURE_OPTIONS}"
exit 1
fi
make clean
PATH=${TOOLCHAIN_BIN_PATH}:${PATH} \
make build_libs
if [[ $? -ne 0 ]]; then
echo "Error executing make for platform:${SQLCIPHER_TARGET_PLATFORM}"
exit 1
fi
mkdir -p ${ANDROID_LIB_ROOT}/${SQLCIPHER_TARGET_PLATFORM}
mv libcrypto.a ${ANDROID_LIB_ROOT}/${SQLCIPHER_TARGET_PLATFORM}
done
)
- OpenSSLのソースをダウンロードして、展開する
$ curl -L https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz -o openssl-3.4.0.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 17.4M 100 17.4M 0 0 13.0M 0 0:00:01 0:00:01 --:--:-- 82.0M
$ tar -zxvf openssl-3.4.0.tar.gz
- OpenSSLのリポジトリにもandroid向けのビルドについて説明があるので参考にする
NOTES-ANDROID.md
Apart from `PATH` adjustment, you need to set `ANDROID_NDK_ROOT` environment
to point at the `NDK` directory. If you're using a side-by-side NDK the path
will look something like `/some/where/android-sdk/ndk/<ver>`, and for a
standalone NDK the path will be something like `/some/where/android-ndk-<ver>`.
Both variables are significant at both configuration and compilation times.
The NDK customarily supports multiple Android API levels, e.g. `android-14`,
`android-21`, etc. By default, latest API level is chosen. If you need to target
an older platform pass the argument `-D__ANDROID_API__=N` to `Configure`,
with `N` being the numerical value of the target platform version. For example,
to compile for Android 10 arm64 with a side-by-side NDK r20.0.5594570
export ANDROID_NDK_ROOT=/home/whoever/Android/android-sdk/ndk/20.0.5594570
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__=29
make
-
ANDROID_NDK_ROOT
なるものを設定し、NDKに含まれているLLVMのclang
にPATHを通す
$ export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk/27.2.12479018
$ PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin:$PATH
-
./Configure
を実行する
$ ./Configure android-arm64 -D__ANDROID_API__=29
Configuring OpenSSL version 3.4.0 for target android-arm64
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created Makefile.in
Created Makefile
**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL.md file first) ***
*** ***
**********************************************************************
- 作成された
Makefile
を見てみる(36000行のMakefileが生成されたので抜粋)
Makefile
Makefile
##
## Makefile for OpenSSL
##
## WARNING: do not edit!
## Generated by configdata.pm from Configurations/common0.tmpl, Configurations/unix-Makefile.tmpl
## via Makefile.in
PLATFORM=android-arm64
OPTIONS=-D__ANDROID_API__=29 no-acvp-tests no-afalgeng no-asan no-brotli no-brotli-dynamic no-buildtest-c++ no-crypto-mdebug no-crypto-mdebug-backtrace no-demos no-devcryptoeng no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fips no-fips-post no-fips-securitychecks no-fuzz-afl no-fuzz-libfuzzer no-h3demo no-jitter no-ktls no-md2 no-msan no-pie no-rc5 no-sctp no-ssl3 no-ssl3-method no-tfo no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-winstore no-zlib no-zlib-dynamic no-zstd no-zstd-dynamic
CONFIGURE_ARGS=("android-arm64", "-D__ANDROID_API__=29")
SRCDIR=.
BLDDIR=.
FIPSKEY=f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813
VERSION=3.4.0
VERSION_NUMBER=3.4.0
MAJOR=3
MINOR=4
SHLIB_VERSION_NUMBER=3
SHLIB_TARGET=linux-shared
LIBS=apps/libapps.a libcrypto.a libssl.a providers/libcommon.a \
providers/libdefault.a providers/liblegacy.a test/libtestutil.a
SHLIBS=libcrypto.so libssl.so
SHLIB_INFO="libcrypto.so;;" "libssl.so;;"
MODULES=engines/capi.so engines/dasync.so engines/loader_attic.so \
engines/ossltest.so engines/padlock.so providers/legacy.so \
test/p_minimal.so test/p_test.so
FIPSMODULE=
FIPSMODULENAME=
- Makefileを見ると以下のコマンドを実行すれば
libcrypto.a
が生成される
$ make build_modules
$ make libcrypto.a
-
build-openssl-libraries.sh
を見る限り、他にもオプションをつけてビルドするようだが一旦このままplatform分のlibcrypto.a
を生成する
# SQLCipher4.6.0に合わせてAPI Level 21でビルドする
$ ./Configure android-arm64 -D__ANDROID_API__=21
$ make clean build_modules libcrypto.a
$ mkdir -p ./../arm64-v8a
$ mv libcrypto.a ./../arm64-v8a
$ ./Configure android-arm -D__ANDROID_API__=21
$ make clean build_modules libcrypto.a
$ mkdir -p ./../armeabi-v7a
$ mv libcrypto.a ./../armeabi-v7a
$ ./Configure android-x86_64 -D__ANDROID_API__=21
$ make clean build_modules libcrypto.a
$ mkdir -p ./../x86_64
$ mv libcrypto.a ./../x86_64
$ ./Configure android-x86 -D__ANDROID_API__=21
$ make clean build_modules libcrypto.a
$ mkdir -p ./../x86
$ mv libcrypto.a ./../x86
SQLCipherのビルド
- sqlcipher/android-database-sqlcipherにそれっぽいスクリプトがあるので参考にする
native.gradle
native.gradle
task buildAmalgamation() {
onlyIf {
def amalgamation = new File("${sqlcipherDir}/sqlite3.c")
return !amalgamation.exists()
}
doLast {
exec {
workingDir "${sqlcipherDir}"
environment("CFLAGS", "${sqlcipherCFlags}")
commandLine "./configure", "--enable-tempstore=yes", "--with-crypto-lib=none"
}
exec {
workingDir "${sqlcipherDir}"
environment("CFLAGS", "${sqlcipherCFlags}")
commandLine "make", "sqlite3.c"
}
}
}
task copyAmalgamation() {
doLast {
exec {
workingDir "${sqlcipherDir}"
commandLine "cp", "sqlite3.c", "sqlite3.h", "${nativeRootOutputDir}/cpp/"
}
}
}
- 解読すると以下の通りになりそう
- sqlcipher/sqlcipherをcloneする
-
CFLAGS
を設定する -
./configure --enable-tempstore=yes --with-crypto-lib=none
を実行する -
make sqlite3.c
を実行する
- 設定する
CFLAGS
はsqlcipher/sqlcipher-androidのAndroid.mkを参考にすればよい
sqlcipher/Android.mk
sqlcipher/Android.mk
ifdef $SSQLCIPHER_CFLAGS
LOCAL_CFLAGS += ${SQLCIPHER_CFLAGS}
else
LOCAL_CFLAGS += -DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_TEMP_STORE=2 \
-DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS4_UNICODE61 -DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_RTREE \
-DSQLITE_SOUNDEX -DHAVE_USLEEP -DSQLITE_ENABLE_LOAD_EXTENSION -DSQLITE_ENABLE_STAT3 \
-DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_MAX_VARIABLE_NUMBER=99999 \
-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 -DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_DBSTAT_VTAB
endif
- つまり👇みたいな形になる
$ export CFLAGS='-DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_TEMP_STORE=2 \
-DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS4_UNICODE61 -DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_RTREE \
-DSQLITE_SOUNDEX -DHAVE_USLEEP -DSQLITE_ENABLE_LOAD_EXTENSION -DSQLITE_ENABLE_STAT3 \
-DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_MAX_VARIABLE_NUMBER=99999 \
-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 -DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_DBSTAT_VTAB'
$ ./configure --enable-tempstore=yes --with-crypto-lib=none
$ make sqlite3.c
生成したファイルを配置する
OpenSSL
- 生成したplatformごとの
libcrypto.a
をsqlcipher-android/sqlcipher/src/main/jni/sqlcipher/android-libs
ディレクトリに配置する -
include
ディレクトリ配下のファイル群をsqlcipher-android/sqlcipher/src/main/jni/sqlcipher/android-libs/include
ディレクトリに配置する
SQLCipher
- 生成した
sqlite3.c
,sqlite3.h
をsqlcipher-android/sqlcipher/src/main/jni/sqlcipher
ディレクトリに配置する
ビルド
- ここまでやれば
sqlcipher-android
をビルドするだけで良い
$ ./gradlew assemble
> Task :sqlcipher:buildNdkBuildDebug[arm64-v8a]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildDebug[armeabi-v7a]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildDebug[x86]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildDebug[x86_64]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:processDebugManifest
package="net.zetetic.database" found in source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="net.zetetic.database" from the source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
> Task :sqlcipher:compileDebugJavaWithJavac
ノート:一部の入力ファイルは推奨されないAPIを使用またはオーバーライドしています。
ノート:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
> Task :sqlcipher:buildNdkBuildRelease[arm64-v8a]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildRelease[armeabi-v7a]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildRelease[x86]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:buildNdkBuildRelease[x86_64]
C/C++: fcntl(): Bad file descriptor
> Task :sqlcipher:compileReleaseJavaWithJavac
ノート:一部の入力ファイルは推奨されないAPIを使用またはオーバーライドしています。
ノート:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
> Task :sqlcipher:processReleaseManifest
package="net.zetetic.database" found in source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="net.zetetic.database" from the source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
> Task :sqlcipher:compileReleaseNoX86JavaWithJavac
ノート:一部の入力ファイルは推奨されないAPIを使用またはオーバーライドしています。
ノート:詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
> Task :sqlcipher:processReleaseNoX86Manifest
package="net.zetetic.database" found in source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="net.zetetic.database" from the source AndroidManifest.xml: ~/sqlcipher-android/sqlcipher/src/main/AndroidManifest.xml.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.9/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD SUCCESSFUL in 1m 51s
93 actionable tasks: 83 executed, 10 up-to-date
16KBページサイズ対応
-
Android.mk
を使用しているプロジェクトは以下の記述を追加してビルドし直す
Android.mk
LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
ここまでやってみたものの・・・・・・・
net.zetetic:android-database-sqlcipher
の後継であるnet.zetetic:sqlcipher-android
の最新バージョンでは16KBページサイズに対応済みだった・・・・😩
のでSQLCipherを使う場合は大人しくnet.zetetic:sqlcipher-android
の最新を使えばよい
❌ net.zetetic:android-database-sqlcipher:X.X.X
❌ net.zetetic:sqlcipher-android:4.6.0
⭕️ net.zetetic:sqlcipher-android:4.6.1
まとめ
- 16KBページサイズ対応が必要か確認するときは
check_elf_alignment.sh
を使おう - androidでSQLCipherを使いたい時は
net.zetetic:android-database-sqlcipher
ではなくnet.zetetic:sqlcipher-android
の4.6.1以上を使おう