新闻详情

新闻详情

首页 / 资讯中心 / 详情

Tuta 项目 Android SQLCipher 构建全流程指南:用容器化工具链从源码编译 sqlcipher-android.aar

发布时间:2026/9/27 7:29:02来源:尧图网络
Tuta 项目 Android SQLCipher 构建全流程指南:用容器化工具链从源码编译 sqlcipher-android.aar
协同办公密码学【免费下载链接】tutanotaTuta is an email service with a strong focus on security and privacy that lets you encrypt emails, contacts and calendar entries on all your devices.项目地址https://gitcode.com/gh_mirrors/tu/tutanota点击查看免费下载SQLCipher for Android 并不是开箱即用的依赖它自身还依赖 OpenSSL 与 SQLCipher 两个底层库必须按顺序交叉编译后才能产出可供 Android 工程引用的 AAR 包。本文以 Tutatutanota仓库中的 README-android-sqlcipher.md 为骨架结合仓库内完整的 Dockerfile、版本文件与两套 Shell 构建脚本逐步讲解从环境准备、镜像构建、参数注入到产物落地的整条编译链路并延伸到 Tuta Android 客户端如何加载并实际使用这颗 SQLCipher 库。读完本文你将掌握用 Podman 复现 Tuta 官方 SQLCipher Android 构建环境的完整方法理解其中每一个版本号、编译开关和 ABI 参数的含义。一、为什么 Tuta 要自建 SQLCipher for AndroidSQLCipher 是 SQLite 的加密扩展通过在原有数据库格式之上叠加 AES-256 页面级加密使落盘的数据库文件无法被直接读取。Tuta 的 Android 端邮件、日历、云盘三款应用依靠它在本地加密存储离线邮件、日历事件等敏感数据。然而正如 README-android-sqlcipher.md 开头所指出的SQLCipher for Android 并不是batteries included在它能够被构建之前必须先构建好两个外部依赖OpenSSL或其它加密提供方——Tuta 当前使用 OpenSSL作为 SQLCipher 的密码学后端SQLCIPHER_CRYPTO_OPENSSLSQLCipher 本体——需要先生成其 amalgamation 源码sqlite3.c/sqlite3.h再喂给 android-sqlcipher 的 JNI 层进行 NDK 编译。上游 SQLCipher 的官方构建说明中同样维护着一份 external-dependencies 清单指向的就是这两项依赖。仓库中的libs/sqlcipher-android/目录正是为此准备的一键自建工具共包含四个文件README-android-sqlcipher.md——构建总说明与顶层命令android-sqlcipher-ver——版本号声明文件android-sqlcipher.dockerfile——承载全部构建工具链的容器镜像定义build-sqlcipher-android.sh 与 build-openssl-libraries.sh——容器入口脚本及其调用的 OpenSSL 交叉编译脚本。构建出的最终产物是sqlcipher-android-4.7.2-release.aar仓库把它固定在 app-android/libs/sqlcipher-android.aar并由各 Android 模块通过 Gradle 直接以本地文件依赖方式引用详见下文产物落地一节。从源码结构看Tuta 之所以选择在仓库内自带整套构建工具并内置预编译 AAR是为了在保持加密数据库能力的同时精确锁定 SQLCipher 的编译开关与 OpenSSL 的裁剪策略从而控制二进制体积并满足自有功能需求如 FTS5 扩展加载。二、构建流程总览与顶层命令README 给出的核心操作只有三步准备输出目录、构建镜像、以参数化方式运行容器。原文档中的命令如下可直接复制执行mkdir build-sqlcipher podman build -t android-sqlcipher --networkhost -f android-sqlcipher.dockerfile source android-sqlcipher-ver podman run --rm \ -e SQLCIPHER_VERSION$SQLCIPHER_VERSION \ -e SQLCIPHER_ANDROID_VERSION$SQLCIPHER_ANDROID_VERSION \ -v $(pwd):/workspace:ro \ -v $(pwd)/build-sqlcipher:/build-sqlcipher \ -it android-sqlcipher # This will produce the artifact at build-sqlcipher/sqlcipher-android-4.7.2-release.aar # Move it to its final destination mv build-sqlcipher/sqlcipher-android-${SQLCIPHER_ANDROID_VERSION}-release.aar ../../app-android/libs/sqlcipher-android.aar各命令与参数的含义如下命令/参数作用说明mkdir build-sqlcipher创建产物输出目录容器内/build-sqlcipher通过卷挂载映射到该目录AAR 最终落在宿主机此目录下podman build -t android-sqlcipher --networkhost构建构建工具镜像--networkhost让容器直接使用宿主机网络保证后续git clone上游源码OpenSSL、SQLCipher时网络策略一致、不易被容器 DNS/代理干扰source android-sqlcipher-ver加载版本号到当前 Shell 环境该文件内容为SQLCIPHER_VERSION4.7.0、SQLCIPHER_ANDROID_VERSION4.7.2导出为环境变量后供podman run使用-e SQLCIPHER_VERSION/-e SQLCIPHER_ANDROID_VERSION向容器注入版本变量容器内构建脚本依赖这两个变量决定克隆哪个 tag、产出哪个版本号的 AAR-v $(pwd):/workspace:ro只读挂载仓库工作区构建脚本build-sqlcipher-android.sh、build-openssl-libraries.sh已在镜像构建时 COPY 进容器此挂载主要供中间产物读写写入android-database-sqlcipher目录ro防止误改仓库-v $(pwd)/build-sqlcipher:/build-sqlcipher挂载产物输出目录对应镜像内环境变量ANDROID_SQLCIPHER_OUTPUT_DIR/build-sqlcipher/脚本末尾将 AARmv到这里-it交互式运行镜像默认 CMD 直接执行构建脚本传入其它参数时如 CI 场景可覆盖入口执行自定义命令mv ... ../../app-android/libs/sqlcipher-android.aar产物归位注意此处的../../是相对 README 所在目录libs/sqlcipher-android/而言的最终落到app-android/libs/下覆盖仓库内置的预编译 AAR值得说明的是README 中mv的../../是相对于文档自身位置的写法实际仓库结构中产物最终路径是 app-android/libs/sqlcipher-android.aar。如果你在仓库根目录执行顶层命令则应把目标路径直接写为app-android/libs/sqlcipher-android.aar。三、版本控制android-sqlcipher-ver 里的两个版本号android-sqlcipher-ver 全文仅两行却控制着整条构建链路的关键输入SQLCIPHER_VERSION4.7.0 SQLCIPHER_ANDROID_VERSION4.7.2SQLCIPHER_VERSION4.7.0上游 sqlcipher/sqlcipher 仓库的标签版本。构建脚本会用git checkout v$SQLCIPHER_VERSION检出对应 tag然后configure并make sqlite3.c生成 amalgamation 源码SQLCIPHER_ANDROID_VERSION4.7.2android-sqlcipher 仓库的版本。Tuta 使用的是自己的 forkgit checkout v${SQLCIPHER_ANDROID_VERSION}-tutaotag 形如v4.7.2-tutaofork 中加入了 Tuta 需要的定制能力例如允许在打开数据库后加载 FTS5 tokenizer 扩展。最终 AAR 文件名sqlcipher-android-4.7.2-release.aar正是取自该变量。两个版本并非必须一致前者是 SQLite/SQLCipher 内核版本后者是 Android 封装层JNI Gradle 工程的版本。升级任一方时需要确认 fork 分支与内核版本相互兼容。四、构建镜像拆解android-sqlcipher.dockerfileandroid-sqlcipher.dockerfile 把整套交叉编译工具链固化进容器其关键设计点如下FROM quay.io/toolbx-images/debian-toolboxsha256:4ebacb09e266143c6394bc6e130495082407cf4511043de7458a27267dccf083 WORKDIR / ENV ANDROID_NDK_VERSION25.2.9519653 ENV ANDROID_SQLCIPHER_OUTPUT_DIR/build-sqlcipher/ RUN apt update apt install -y curl openjdk-21-jdk-headless gcc tclsh make RUN curl https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -o sdk-tools.zip \ unzip sdk-tools -d /android_sdk \ mkdir /tmp/cmdlinetools-latest \ mv /android_sdk/cmdline-tools/* /tmp/cmdlinetools-latest \ mv /tmp/cmdlinetools-latest /android_sdk/cmdline-tools/latest \ yes | /android_sdk/cmdline-tools/latest/bin/sdkmanager --licenses \ /android_sdk/cmdline-tools/latest/bin/sdkmanager ndk;$ANDROID_NDK_VERSION \ chmod 777 -R /android_sdk # needs to be writeable when downloading sdk/ndk later ENV ANDROID_HOME/android_sdk COPY build-sqlcipher-android.sh build-sqlcipher-android.sh COPY build-openssl-libraries.sh build-openssl-libraries.sh # Do not override entrypoint as Jenkins plugin expects to run commands inside of it # Running the container without any arguments will just run the script, otherwise the user can run another command if # passsed in. CMD /build-sqlcipher-android.sh逐项解读基础镜像quay.io/toolbx-images/debian-toolbox按 digest 固定提供 Debian 系工具链NDK 版本ANDROID_NDK_VERSION25.2.9519653NDK r25c由 sdkmanager 下载安装到/android_sdk/ndk/构建脚本通过$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION定位 NDK宿主依赖curl下载 SDK 工具、openjdk-21-jdk-headlessAAR 打包与 Gradle 需要 JVM、gcc宿主机编译辅助、tclshSQLite 的configure依赖 Tcl、make构建驱动Android SDK 布局cmdline-tools 11076708 被移动到标准位置/android_sdk/cmdline-tools/latest随后sdkmanager --licenses接受许可并安装 NDKchmod 777 -R /android_sdk的注释说明该目录在后续运行阶段仍需可写OpenSSL 与 SQLCipher 的构建产物会写入其中入口设计CMD /build-sqlcipher-android.sh。注释特别强调不要覆盖 entrypoint因为 Jenkins 插件需要在容器内执行命令因此不带参数运行容器时执行默认构建脚本传入其它命令时则执行自定义命令。镜像构建阶段只 COPY 了两个脚本实际的源码克隆、交叉编译都发生在podman run阶段——这样镜像层保持轻量版本参数SQLCIPHER_VERSION等可以在每次运行时灵活注入而无需重建镜像。五、镜像内构建脚本build-sqlcipher-android.sh 全流程build-sqlcipher-android.sh 是容器默认执行的入口脚本set -exu开启严格模式任何命令失败立即退出、逐条打印执行的命令。整条流水线可分为六个阶段5.1 克隆 OpenSSL 与 SQLCipher 源码# clone OpenSSL, needed as part of the build of both old and new sqlcipher git clone https://github.com/openssl/openssl pushd openssl git checkout openssl-3.5.1 popd # Clone the main SQLCipher repo git clone https://github.com/sqlcipher/sqlcipher pushd sqlcipher git checkout v$SQLCIPHER_VERSION popdOpenSSL 固定在openssl-3.5.1tagSQLCipher 依据$SQLCIPHER_VERSION环境变量即上文android-sqlcipher-ver中的4.7.0检出对应 tag。这就是podman run必须使用--networkhost的原因——容器启动后需要实时访问 GitHub 拉取源码。5.2 SQLCIPHER_CFLAGSSQLite 内核的编译开关矩阵export ANDROID_NDK_HOME$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION export ANDROID_NDK_ROOT$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION # depreacted are still used (trace) # utf16 is needed because java # memory stats are used for something too # progress is used for cancellation export SQLCIPHER_CFLAGS-DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_USE_URI0 \ -DSQLITE_OMIT_AUTOINIT -DSQLITE_OMIT_DESERIALIZE -DSQLITE_OMIT_GET_TABLE \ -DSQLITE_OMIT_TCL_VARIABLE -DSQLITE_OMIT_COMPLETE \ -DSQLITE_OMIT_AUTHORIZATION -DSQLITE_DEFAULT_FOREIGN_KEYS1 -DSQLITE_DQS0 -DSQLITE_ENABLE_MATH_FUNCTIONS \ -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_HAS_CODEC -DSQLITE_SOUNDEX -DHAVE_USLEEP1 \ -DSQLITE_MAX_VARIABLE_NUMBER99999 -DSQLITE_TEMP_STORE3 -DSQLITE_THREADSAFE1 \ -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT1048576 -DNDEBUG1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT1 \ -DSQLITE_ENABLE_LOAD_EXTENSION -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_STAT4 \ -DSQLITE_ENABLE_FTS5 -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_EXTRA_INITsqlcipher_extra_init \ -DSQLITE_EXTRA_SHUTDOWNsqlcipher_extra_shutdown \ -Wno-macro-redefined这批宏定义是 SQLCipher 内核行为的总开关其中几组值得重点理解加密与全文检索SQLITE_HAS_CODEC启用 SQLCipher 页面加密SQLCIPHER_CRYPTO_OPENSSL指定以 OpenSSL 作为加密后端对应依赖清单第一项SQLITE_ENABLE_FTS5启用 FTS5 全文搜索引擎——Tuta 的离线搜索与 Signal 分词器见下文 Android 侧loadExtension都建立在其上裁剪SQLITE_OMIT_*AUTOINIT、DESERIALIZE、GET_TABLE、TCL_VARIABLE、COMPLETE、AUTHORIZATION等模块被移除以减小二进制体积、移除不需要的接口面行为与性能SQLITE_DEFAULT_FOREIGN_KEYS1默认开启外键约束SQLITE_THREADSAFE1线程安全模式SQLITE_TEMP_STORE3临时表全部放内存SQLITE_MAX_VARIABLE_NUMBER99999放宽绑定变量上限SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT1048576限制 journal 单文件大小SQLITE_ENABLE_MEMORY_MANAGEMENT开启内存管理回调生命周期钩子SQLITE_EXTRA_INITsqlcipher_extra_init与SQLITE_EXTRA_SHUTDOWNsqlcipher_extra_shutdown注入 SQLCipher 的初始化/收尾函数用于注册加密扩展等全局逻辑其它SQLITE_ENABLE_COLUMN_METADATA、SQLITE_ENABLE_UNLOCK_NOTIFY、SQLITE_ENABLE_STAT4、SQLITE_ENABLE_DBSTAT_VTAB、SQLITE_ENABLE_UPDATE_DELETE_LIMIT、SQLITE_ENABLE_MATH_FUNCTIONS、SQLITE_SOUNDEX、HAVE_USLEEP1等为功能增强SQLITE_LIKE_DOESNT_MATCH_BLOBS、SQLITE_USE_URI0、SQLITE_DQS0属兼容性收紧NDEBUG1关闭断言。脚本注释还解释了保留弃用特性的原因trace 仍在使用、utf16 是 Java 侧需要、memory stats 与 progress 分别服务于统计和取消操作。5.3 交叉编译 OpenSSL产出四个 ABI 的 libcrypto.aexport SQLCIPHER_ROOT$PWD/sqlcipher export OPENSSL_ROOT$PWD/openssl export nativeRootOutputDir$PWD/android-database-sqlcipher/android-database-sqlcipher/src/main export androidNativeRootDir$PWD/${nativeRootOutputDir}/external/android-libs export minimumAndroidSdkVersion21 export minimumAndroid64BitSdkVersion21 bash ./build-openssl-libraries.sh ${minimumAndroidSdkVersion} ${minimumAndroid64BitSdkVersion} ${OPENSSL_ROOT} ${androidNativeRootDir}脚本 build-openssl-libraries.sh 源自上游 sqlcipher 的 android-database-sqlcipher 项目。它按四个 ABI 循环执行 OpenSSL 的Configuremake build_generated libcrypto.aABIConfigure 架构参数API 级别位数armeabi-v7aandroid-arm -marcharmv7-a2132x86android-x862132x86_64android64-x86_642164arm64-v8aandroid-arm642164要点最小 SDK 21Tuta 的minimumAndroidSdkVersion与minimumAndroid64BitSdkVersion均为 2132 位与 64 位 ABI 使用同一 API 级别只产 libcrypto.a、不产 libsslmake build_generated libcrypto.a明确跳过 libssl上游注释引用 OpenSSL issue #4597SQLCipher 只需要libcrypto.a中的对称/非对称密码学原语与随机数工具链从$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/host/bin取用 NDK 内 LLVM 交叉编译器宿主识别逻辑处理 Linux/Darwin含 i686 与 x86_64 分支其它平台直接报错退出激进裁剪OPENSSL_CONFIGURE_OPTIONS通过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-engine no-srtp no-des no-comp no-sm3 no-cmac no-legacy no-argon2 no-blake2 no-http no-zlib no-zstd no-deprecated no-dgram no-tls no-cmp no-aria no-winstore no-chacha no-cms no-ct no-docs no-dso no-http no-integrity-only-ciphers no-ml-dsa no-ml-kem no-nextprotoneg no-ocb no-ocsp no-poly1305 no-psk no-rmd160 no-scrypt no-siphash no-slh-dsa no-sm2-precomp no-sm4 no-ssl no-ssl-trace no-tests no-ts no-ui-console no-uplink关闭了大量不需要的算法与子系统脚本内注释逐项列出了 OpenSSL Configure 的完整 feature 清单及取舍理由同时开启-fPIC -fstack-protector-all与-Wno-macro-redefined。由于 SQLCipher 实际只用少量原语AES、RSA、随机数等这种裁剪能显著缩小最终库体积产物落位每个 ABI 的libcrypto.a被移动到${ANDROID_LIB_ROOT}/${ABI}/即android-database-sqlcipher/android-database-sqlcipher/src/main/external/android-libs/abi/libcrypto.a。5.4 生成 SQLCipher amalgamation 源码pushd $SQLCIPHER_ROOT CFLAGS$SQLCIPHER_CFLAGS ./configure --with-tempstoreyes CFLAGS$SQLCIPHER_CFLAGS make sqlite3.c mkdir -p $nativeRootOutputDir/cpp/ cp sqlite3.c sqlite3.h $nativeRootOutputDir/cpp/ popdSQLite 的发布形态是amalgamation——把全部核心源码合并为单个sqlite3.csqlite3.h便于嵌入式编译。此处在注入上述SQLCIPHER_CFLAGS的前提下执行configure --with-tempstoreyes并make sqlite3.c生成带全部定制开关的单文件内核随后复制到android-database-sqlcipher/.../src/main/cpp/备用。5.5 检出 Tuta 的 sqlcipher-android fork 并装配 JNI 源# Clone the new android-sqlcipher repo git clone https://github.com/tutao/sqlcipher-android/ pushd sqlcipher-android git checkout v${SQLCIPHER_ANDROID_VERSION}-tutao popd # opy the artifacts to the library cp $nativeRootOutputDir/cpp/sqlite3.c $nativeRootOutputDir/cpp/sqlite3.h sqlcipher-android/sqlcipher/src/main/jni/sqlcipher/ cp -R $androidNativeRootDir sqlcipher-android/sqlcipher/src/main/jni/sqlcipher/ cp -R $OPENSSL_ROOT/include/ sqlcipher-android/sqlcipher/src/main/jni/sqlcipher/android-libs/Tuta 使用自己的 forktagv4.7.2-tutao而不是上游 signalapp 的版本fork 中保留了加载自定义 FTS5 分词器扩展的能力对应 Android 侧loadExtension调用见下文。随后把三样东西装进 JNI 目录amalgamation 源码sqlite3.c/h、各 ABI 的libcrypto.a、OpenSSL 头文件include/使 JNI 层源码自洽无需外部依赖即可编译。5.6 产出 AAR 并导出到挂载卷pushd sqlcipher-android make build-release popd # Move the output out of the container mv sqlcipher-android/sqlcipher/build/outputs/aar/sqlcipher-android-$SQLCIPHER_ANDROID_VERSION-release.aar $ANDROID_SQLCIPHER_OUTPUT_DIRmake build-release驱动 fork 内置的 Gradle 任务完成 NDK 编译四个 ABI 的.so与 AAR 打包最终产物sqlcipher-android-4.7.2-release.aar被移动到$ANDROID_SQLCIPHER_OUTPUT_DIR即挂载的宿主机build-sqlcipher/目录实现容器内构建、宿主机取件。六、产物落地与 Android 工程集成6.1 归位到 app-android/libs按 README 的mv命令AAR 最终覆盖 app-android/libs/sqlcipher-android.aar。这一位置被三个可安装应用模块共同引用app/build.gradle.ktsimplementation(files(../libs/sqlcipher-android.aar))calendar/build.gradle.kts同样implementation(files(../libs/sqlcipher-android.aar))drive/build.gradle.kts同样implementation(files(../libs/sqlcipher-android.aar))。而共享库模块 tutashared/build.gradle.kts 使用的是compileOnly(files(../libs/sqlcipher-android.aar))——即编译期可见、运行期由最终 app 提供避免多模块重复打包。6.2 代码加载与使用AndroidSqlCipherFacadeAAR 的 Java 包名为net.zetetic.database.sqlciphernative 库名为sqlcipher。Tuta 在 AndroidSqlCipherFacade.kt 中封装了它的实际用法class AndroidSqlCipherFacade(private val context: Context) : SqlCipherFacade { init { System.loadLibrary(sqlcipher) } ... override suspend fun openDb(userId: String, dbKey: DataWrapper) { synchronized(this) { ... } db SQLiteDatabase.openOrCreateDatabase(getDbFile(userId), dbKey.data, null, null) // Added in fork! openedDb.loadExtension(libsignal_tokenizer, signal_fts5_tokenizer_init) ... } }可以观察到如下关键事实构造时System.loadLibrary(sqlcipher)加载 native 库即 AAR 中打包的加密 SQLite 引擎SQLiteDatabase.openOrCreateDatabase(path, passphrase, ...)以数据库文件的路径和密钥dbKey.data由用户主密钥派生打开加密库密钥即构建流程中SQLITE_HAS_CODEC能力的运行时体现打开后调用loadExtension(libsignal_tokenizer, signal_fts5_tokenizer_init)——这正是 Tuta fork 新增的能力把 libs/Signal-FTS5-Extension 编译出的分词器注入 FTS5 全文索引离线搜索功能随后执行PRAGMA auto_vacuum incremental采用增量自动清理配合关闭前PRAGMA incremental_vacuum做碎片整理、PRAGMA busy_timeout 5000通知进程等多进程场景下的写锁等待上限等数据库维护策略。此外 consumer-rules.pro 中通过-keep class net.sqlcipher.** { *; }与-keep interface net.sqlcipher.** { *; }保留 SQLCipher 的类与接口——注释明确说明we dynamically load sqlcipher, so we should keep the classes around防止 R8 混淆破坏动态加载路径。七、注意事项与常见问题版本一致性SQLCIPHER_VERSION内核4.7.0与SQLCIPHER_ANDROID_VERSIONAndroid 封装层4.7.2是两个独立维度升级任一方需确认 fork tagv4.7.2-tutao与内核版本兼容并重新走完整构建流程网络要求podman build与podman run阶段都需要访问外网下载 SDK/NDK、git cloneOpenSSL/SQLCipher/forkREADME 使用--networkhost规避容器网络策略问题产物目录约定宿主机build-sqlcipher/与容器/build-sqlcipher必须保持挂载对应否则mv到$ANDROID_SQLCIPHER_OUTPUT_DIR会因目标为容器内路径而无法在宿主机取件入口可覆盖镜像CMD为默认构建脚本CI如 Jenkins 插件可传入其它命令在容器内执行但脚本顶部set -exu意味着任何一步失败都会中断并暴露日志便于定位NDK 与 JDK 要求镜像固定 NDK r25c25.2.9519653与 OpenJDK 21宿主机无需安装 Android 工具链若在容器外复现需要自行对齐这些版本混淆与动态加载集成方务必保留net.sqlcipher.**含接口否则运行期System.loadLibrary(sqlcipher)后的反射/动态调用会因类被移除或重命名而崩溃加密密钥管理AAR 只负责用密钥加密数据库密钥本身dbKey由 Tuta 的凭据体系主密钥 Kdf 派生管理不随库分发。八、仓库内相关资源索引构建说明文档libs/sqlcipher-android/README-android-sqlcipher.md版本声明libs/sqlcipher-android/android-sqlcipher-ver容器镜像libs/sqlcipher-android/android-sqlcipher.dockerfile主构建脚本libs/sqlcipher-android/build-sqlcipher-android.shOpenSSL 交叉编译脚本libs/sqlcipher-android/build-openssl-libraries.sh预编译产物app-android/libs/sqlcipher-android.aarGradle 引用示例app-android/app/build.gradle.kts运行时封装app-android/tutashared/src/main/java/de/tutao/tutashared/offline/AndroidSqlCipherFacade.kt混淆保留规则app-android/tutashared/consumer-rules.proFTS5 分词器扩展源码libs/Signal-FTS5-Extension综上Tuta 的 Android SQLCipher 构建方案是一条容器化 版本参数化 产物固定化的完整链路Dockerfile 固化工具链android-sqlcipher-ver控制版本两个 Shell 脚本完成 OpenSSL 交叉编译与 SQLCipher amalgamation 装配最终产出sqlcipher-android-4.7.2-release.aar供三款应用共享。理解这套流程后你既可以原样复现官方构建也可以按需调整编译开关例如增删SQLITE_OMIT_*或 OpenSSL 的no-*裁剪项来定制自己的加密数据库引擎。赞分享协同办公密码学【免费下载链接】tutanotaTuta is an email service with a strong focus on security and privacy that lets you encrypt emails, contacts and calendar entries on all your devices.项目地址https://gitcode.com/gh_mirrors/tu/tutanota点击查看免费下载相关推荐终极指南从SQLCipher for Android迁移到sqlcipher-android的完整步骤终极指南从SQLCipher for Android迁移到sqlcipher android的完整步骤 在Android应用开发中数据安全始终是开发者关注的数据库密码学移动开发SQLCipher for Android 使用指南SQLCipher for Android 使用指南 1. 项目介绍 SQLCipher for Android 是一个基于 SQLCipher 的安卓 SQL数据库密码学移动开发NCRF模型对比分析CharLSTM vs CharCNN vs WordLSTM性能测评终极指南NCRF模型对比分析CharLSTM vs CharCNN vs WordLSTM性能测评终极指南 NCRF是一个强大的神经序列标注工具包专门用于命上一篇让路由器变身智能存储中心ImmortalWrt网络存储完全指南下一篇LibreSprite完整安装教程从零开始快速部署专业像素画工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

如何攻击Wordpress站点常见报错与解决 2026/9/27 8:23:46

如何攻击Wordpress站点常见报错与解决

5个WordPress安全陷阱与防御注意事项 改个需求建站公司拖一周,这种憋屈感谁懂?刚上线的WordPress站点,后台改个按钮颜色,外包团队说“底层逻辑冲突”,得排期。结果第二天网站直接变白屏,或者更糟——被黑客植入了恶意代码,SEO收…

阅读更多 →
themeforestwordpress新手避坑速查手册:别花冤枉钱 2026/9/27 8:23:46

themeforestwordpress新手避坑速查手册:别花冤枉钱

themeforestwordpress新手避坑速查手册:别花冤枉钱 网站做好了没人访问,比没做还让人焦虑。你盯着后台那可怜个位数的UV,心里直打鼓,是不是域名没选对?是不是服务器太慢?别急,这大概率不是玄学,而是技术选型和基础配置的硬伤。…

阅读更多 →
NoneBot2 跨插件访问与依赖声明:深入理解 require 机制与插件加载时序 2026/9/27 8:23:40

NoneBot2 跨插件访问与依赖声明:深入理解 require 机制与插件加载时序

后端即时通讯 【免费下载链接】nonebot2 跨平台 Python 异步聊天机器人框架 / Asynchronous multi-platform chatbot framework written in Python 项目地址: https://gitcode.com/gh_mirrors/no/nonebot2 点击查看 免费下载 跨插件调用是 NoneBot2 插件化架构中的…

阅读更多 →
基于自适应语义路由(Semantic Routing)的知识库多路混合召回实战 2026/9/27 8:23:33

基于自适应语义路由(Semantic Routing)的知识库多路混合召回实战

基于自适应语义路由(Semantic Routing)的知识库多路混合召回实战在企业级大型 RAG(检索增强生成)知识库架构中,企业通常维护着数十个物理隔离、数据形态各异的垂直专业知识库(如:API 技术文档库…

阅读更多 →
Onivim 2 按键绑定(Key Bindings)配置完全指南:keybindings.json 格式、when 条件上下文与命令参考 2026/9/27 8:23:33

Onivim 2 按键绑定(Key Bindings)配置完全指南:keybindings.json 格式、when 条件上下文与命令参考

开发工具代码编辑器桌面应用 【免费下载链接】oni2 Native, lightweight modal code editor 项目地址: https://gitcode.com/gh_mirrors/on/oni2 点击查看 免费下载 Onivim 2 的按键绑定体系在设计上力求与 VSCode 的 Key Bindings 兼容,同时完整保留 V…

阅读更多 →
核心 Web 指标(CWV)2026 最新标准走读与应对 2026/9/27 8:23:26

核心 Web 指标(CWV)2026 最新标准走读与应对

核心 Web 指标(CWV)2026 最新标准走读与应对在 Google 搜索引擎的 SEO 排名权重与现代前端性能工程中,Google 核心 Web 指标(Core Web Vitals,简称 CWV) 是全球衡量真实用户体验(Field Experien…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉