F-Droid 1.23.2 实测报告

把官方 APK 拉到本地逐字节解析:体积构成、权限清单、签名验证、追踪器检测。所有数字均可复现。

这篇不是官方文档的中文翻译。我把 F-Droid 客户端的 APK 安装包下载到本地,用脚本把它当成 ZIP 打开,逐层解析了它的 AndroidManifest、签名块、资源表和两个 DEX 文件,把量出来的结果如实记在这里。文中每一个数字都来自这台机器上的实测,文末给出了复现命令,你可以自己跑一遍核对。

测试样本:F-Droid.apk 实测日期:2026-09-04 样本版本:1.23.2

一、样本基本信息

先看这组最关键的数据。它既是判断文件有没有被改动的依据,也是后面所有分析的起点。

文件大小12,426,276 字节(11.85 MB)
版本名 / 版本号1.23.2 / 1023052
包名org.fdroid.fdroid
最低系统要求Android 6.0(API 23)
目标系统Android 11(API 30)
编译 SDKAndroid 15(API 35)
安装位置auto(由系统决定,允许移至 SD 卡)
包内文件条目1,119 个
SHA-256985f5181d48bb6bafd54083a048b391271e0ab28385881cc41294fb01a222762
SHA-1f94c745d25f13de8bf39e702659c19b6d8ca95b7
MD5ec6a9a8560924bb833942a7c3256847a
签名证书 SHA-25643238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab

二、11.85 MB 里到底装了什么

APK 本质是个 ZIP 包。把 1,119 个条目按目录归并后,体积构成如下。这里同时列出压缩前和压缩后的大小,因为 Android 安装时看的是解压后的体积。

组成部分未压缩压缩后占比文件数
classes2.dex8.66 MB3.37 MB38.37%1
classes.dex8.36 MB3.54 MB37.03%1
resources.arsc(资源索引表)3.91 MB3.91 MB17.34%1
res/ 资源目录1.16 MB0.66 MB5.15%1,067
META-INF 签名与清单0.22 MB0.09 MB0.96%22
kotlin / okhttp3 / org 资源0.16 MB0.06 MB0.69%11
AndroidManifest.xml0.05 MB0.01 MB0.20%1
lib/ 原生库36.5 KB36.5 KB0.16%4
assets/ 资产文件0.02 MB0.02 MB0.08%8

包内解压后的总大小是 22.56 MB,压缩后 11.70 MB,而 APK 文件本身 11.85 MB——多出来的 0.15 MB 是 ZIP 目录结构、4 KB 的 APK 签名块和结尾记录等容器开销。

第一个值得注意的发现:代码占了四分之三。两个 DEX 文件合计 17.01 MB,占解压总量的 75.4%。这意味着 F-Droid 客户端几乎全部由 Java/Kotlin 代码实现。

第二个发现更极端:原生库只有 36.5 KB。整个包里只有 1 个 .so 文件(libandroidx.graphics.path.so),为 4 种 CPU 架构各打了一份,加起来 36.5 KB,占全包 0.158%。具体是:

CPU 架构设备类型库大小
arm64-v8a主流安卓手机(64 位)9.9 KB
armeabi-v7a老旧安卓手机(32 位)7.1 KB
x86_6464 位平板 / 模拟器10.5 KB
x8632 位平板 / 模拟器9.1 KB

几乎没有原生代码,带来两个实际好处:一是同一份安装包能覆盖从老旧 32 位手机到 x86 模拟器的全部设备类型,不需要按架构分发;二是原生代码是安全审计最难的部分,代码量越小,可被隐藏的东西越少。

另外,resources.arsc 有 3.91 MB,占 17.34%,这个比例偏高。原因是 F-Droid 客户端内置了大量多语言字符串资源,语言资源都集中在这张表里。

三、签名验证:怎么确认这个包没被改过

这是下载站最该做也最少做的一步。我用二进制方式定位并解析了 APK 里的签名块,结果是这个包同时带有 v1、v2、v3 三代签名,外加一个 verity 完整性校验块。

签名方案标识 / 位置适配系统实测结果
v1(JAR 签名)META-INF/CIARANG.SF、CIARANG.RSA全部 Android 版本存在
v2(APK 签名方案 v2)签名块 ID 0x7109871aAndroid 7.0 及以上存在
v3(APK 签名方案 v3)签名块 ID 0xf05368c0Android 9.0 及以上存在
verity(完整性校验)签名块 ID 0x42726577Android 11 及以上存在

签名证书的主体信息是 C=UK, CN=Ciaran Gultnieks,有效期到 2037 年 12 月 8 日。这个 CN 正是 F-Droid 项目创始人的名字,也是 F-Droid 官方客户端一直使用的签名密钥。证书有效期一直排到 2037 年,不是那种几个月就过期的临时签名。

这三代签名是递进关系,不是重复劳动:v1 是老的 JAR 签名,兼容所有系统但校验粒度粗;v2 从 Android 7.0 起对整个 APK 做分块哈希校验,改一个字节就会失败;v3 从 Android 9.0 起支持签名密钥轮换,v3 块里带 minSDK / maxSDK 字段。只要这三个签名都能通过校验,就能确定这个包从官方构建出来之后没有被改过、没有被重新打包、没有被人塞入额外代码。

四、权限清单:28 项权限逐条看

从 AndroidManifest 里解析出 28 项权限声明。数量听起来不少,但对一个应用商店来说是正常范围——它要下载、要安装、要管理更新。关键是看每一项有没有对应到具体功能。下面按用途分成四类。

4.1 应用商店的核心能力(12 项)

权限用途
INTERNET连接软件仓库,下载应用索引和 APK
ACCESS_NETWORK_STATE判断当前是否联网、是 Wi-Fi 还是移动数据
ACCESS_WIFI_STATE获取 Wi-Fi 信息,用于局域网内互换应用
REQUEST_INSTALL_PACKAGES请求安装 APK,应用商店的核心权限
REQUEST_DELETE_PACKAGES请求卸载应用
UPDATE_PACKAGES_WITHOUT_USER_ACTION自动更新应用时不再逐个弹窗(需用户先授权)
FOREGROUND_SERVICE下载和安装过程在前台服务中运行,不会被系统杀掉
POST_NOTIFICATIONS发出「有应用可更新」的通知
RECEIVE_BOOT_COMPLETED开机后自动检查应用更新
WAKE_LOCK下载大文件时保持 CPU 唤醒
MANAGE_EXTERNAL_STORAGE读写存储中的 APK 文件与本地仓库
QUERY_ALL_PACKAGES读取已安装应用列表,用于比对版本判断更新

其中 QUERY_ALL_PACKAGES 是 Google Play 政策里管得最严的一项,因为它能看到设备上装了什么。但对应用商店来说,不知道已装应用的版本就无法判断哪些需要更新,属于功能必需。F-Droid 的处理方式是:这个列表只在本地比对,不上报。

4.2 局域网互换应用(8 项)

F-Droid 有一个特色功能:两台手机之间不经过服务器,直接通过局域网、蓝牙或 NFC 互传已下载的应用。这在没网的环境下很有用,代价就是需要下面这些权限。

权限用途
CHANGE_WIFI_MULTICAST_STATE局域���内组播发现附近设备
CHANGE_NETWORK_STATE开启本地热点做应用互换
CHANGE_WIFI_STATE同上,控制 Wi-Fi 状态
BLUETOOTH蓝牙互换应用(旧版蓝牙权限)
BLUETOOTH_ADMIN管理蓝牙配对(旧版蓝牙权限)
BLUETOOTH_SCAN扫描附近蓝牙设备(Android 12 起)
BLUETOOTH_CONNECT连接蓝牙设备传文件(Android 12 起)
USB_PERMISSION通过 USB 与电脑或其他设备互换应用

4.3 其他功能权限(6 项)

权限用途
NFC两台手机背靠背 NFC 触碰即可传送应用
CAMERA扫描二维码添加第三方软件仓库
READ_EXTERNAL_STORAGE读取存储中已有的 APK 文件
WRITE_EXTERNAL_STORAGE把下载的 APK 写入存储
ENFORCE_UPDATE_OWNERSHIP声明应用更新所有权,防止其他商店抢更新
WRITE_SETTINGS修改部分系统设置项

CAMERA 只用于扫二维码加仓库,不用于拍照录像,这一点可以在实际使用中验证:不扫码时系统不会弹出相机调用提示。

4.4 应用自定义权限(2 项)

剩下两项不是向系统申请的权限,而是 F-Droid 自己声明的,用于组件间通信隔离:

  • org.fdroid.fdroid.permission.UPDATE_REPOS — 保护仓库更新接口,只允许自身调用
  • org.fdroid.fdroid.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION — AndroidX 自动生成的权限,用于防止动态广播接收器被外部应用调用

五、追踪器与广告 SDK 检测:零命中

这是很多人关心 F-Droid 的核心原因。我把两个 DEX 文件里的字符串全部提取出来(共 370 万字符),逐一比对常见的商业追踪与广告 SDK 特征。

检测项类型结果
Google Analytics行为分析✓ 未发现
Firebase Analytics行为分析✓ 未发现
Firebase Crashlytics崩溃上报✓ 未发现
AppsFlyer归因追踪✓ 未发现
Adjust归因追踪✓ 未发现
Facebook SDK社交追踪✓ 未发现
友盟 Umeng国内统计✓ 未发现
腾讯 Bugly崩溃上报✓ 未发现
Sentry错误监控✓ 未发现
AdMob广告✓ 未发现

10 项商业追踪与广告 SDK,全部零命中。这个结果也印证了 F-Droid 的收录原则:官方仓库里的应用不允许包含专有追踪器,客户端自身同样遵守这条规则。

5.1 那么包里到底有哪些第三方组件

排除了商业追踪之后,我统计了确实存在的开源组件:

组件用途命中次数
OkHttp3网络请求库(Apache 2.0)303
BouncyCastle加密与证书校验(含 APK 签名校验)500
Kotlin 协程异步任务调度59
Glide / Coil应用图标加载20
SLF4J日志门面3
ACRA崩溃报告(详见下方说明)2
关于 ACRA,需要单独说明。包内确实带有 ACRA 崩溃报告组件(org.acra.*)。但它的工作方式和 Crashlytics 完全不同:ACRA 默认处于关闭状态,只有当你主动开启后,应用在发生崩溃时才会弹出对话框,让你手动选择要不要把崩溃日志发送出去。它不会在后台静默上传任何东西。这与「默认开启、静默上传」的商业崩溃上报有本质区别。

5.2 DEX 里硬编码的域名

从两个 DEX 中提取到 33 个不同的硬编码域名。我逐一核对,全部是开源项目的基础设施,没有一个属于广告、统计或数据变现服务商。以下是其中具有代表性的一部分:

域名用途
f-droid.orgF-Droid 官方主仓库
github.com应用源码仓库链接
gitlab.com 系列部分应用的源码托管
guardianproject.infoGuardian Project 第三方仓库
apt.izzysoft.deIzzyOnDroid 第三方仓库
briarproject.orgBriar 项目仓库
microg.orgmicroG 项目相关
gateway.ipfs.ioIPFS 网关,用于分布式仓库
liberapay.com / opencollective.com开源项目捐赠渠道
spdx.org开源许可证标识标准
flattr.com创作者小额打赏
www.bouncycastle.org / www.slf4j.org所依赖开源库官网

整张域名清单的性质很一致:要么是软件仓库地址,要么是开源项目的主页和捐赠页,要么是所依赖开源库的官网。没有出现任何一家广告联盟、数据统计或用户画像服务商的域名。

六、中文支持:内置简体中文界面

我解析了 resources.arsc 的资源字符串池,共 44,157 条字符串。在其中直接检索到「应用」「下载」「设置」「更新」「安装」「权限」「搜索」「仓库」「版本」等简体中文界面文案,说明客户端内置简体中文,安装完成后无需额外下载语言包

3.91 MB 的 resources.arsc 能占到全包 17.34%,正是因为它把包括中文在内的多语言字符串资源都打包了进去。

七、两个值得留意的细节

7.1 targetSdk 停在 30,而 compileSdk 已经是 35

实测数据里有一处看起来矛盾的地方:这个包是用 Android 15(API 35)的 SDK 编译的,最低支持 Android 6.0(API 23),但 targetSdkVersion 只设到了 30(Android 11)。

这是有意为之,不是偷懒。从 Android 11 之后,Google 对存储权限、软件包可见性、后台活动等一系列行为做了收紧。F-Droid 作为一个需要在前台管理 APK 文件和已装应用列表的应用商店,如果贸然提升 targetSdk,部分核心功能(比如直接读写存储里的 APK、完整的已装应用列表)会被系统限制掉。

代价是:在 Android 12 及以上的设备上,系统会按照旧版兼容行为来运行它,部分新系统的行为变更不会生效。对功能完整性来说这是划算的取舍,但用户应当知道这一点。

7.2 权限数量偏多,但每一项都能对应到功能

28 项权限里,有 8 项是给「局域网 / 蓝牙 / NFC 互换应用」这个功能准备的,6 项是给存储读写和二维码扫码准备的。如果你不需要互换功能,可以在系统设置里单独关掉蓝牙、NFC 相关权限,不影响下载和安装这两个核心功能。

八、自己动手复现这些检测

上面的数据不希望你只信我的结论。以下命令可以在你自己的机器上把关键结果重新跑一遍。

8.1 校验文件哈希

Windows 自带的 certutil 就能算,不需要装任何工具:

certutil -hashfile F-Droid.apk SHA256
certutil -hashfile F-Droid.apk SHA1
certutil -hashfile F-Droid.apk MD5

macOS 或 Linux 用:

sha256sum F-Droid.apk
sha1sum F-Droid.apk
md5sum F-Droid.apk

把输出的十六进制串和本文第一节的表格对照,完全一致就说明你手上的文件和本次测试的是同一个。

8.2 查看签名与证书

需要 Android SDK 的 build-tools,里面有 apksigner:

apksigner verify --verbose --print-certs F-Droid.apk

正常情况下会看到 v1、v2、v3 三行都是 true,证书主体是 CN=Ciaran Gultnieks

8.3 查看包内文件与体积

unzip -l F-Droid.apk

会列出全部 1,119 个条目及其压缩前后大小,可以核对第二节的体积构成表。

8.4 查看权限与版本信息

aapt2 dump badging F-Droid.apk

输出里包含 package name、versionCode、versionName、sdkVersion、targetSdkVersion、uses-permission 全部信息,可核对第四节。

九、结论

把这次实测的结果汇总成一句话:这是一个体积不大(11.85 MB)、几乎纯 Java/Kotlin 实现(原生库仅 36.5 KB)、带 v1+v2+v3 三重签名、不含任何商业追踪与广告 SDK 的应用商店客户端。

几点实际参考价值:

  • 可以放心校验。文内的 SHA-256 和签名证书指纹都是从文件里实测出来的,下载后先比对再安装,是判断文件有没有被人动过手脚最可靠的办法。
  • 老设备友好。最低 Android 6.0,四种 CPU 架构全覆盖,11.85 MB 的体积对存储空间紧张的老机器也友好。
  • 权限虽多但可裁剪。28 项权限大部分能对应到具体实现的功能,不需要互换应用时可以关掉蓝牙、NFC 相关权限。
  • 隐私承诺可被验证。「无追踪」不是一句宣传语,DEX 里的字符串和域名清单可以直接被检视——这次检测的结果是零命中。

需要补充一点:本文的测试对象是 1.23.2 这一个版本。后续版本更新后,体积、权限、SDK 版本都可能变化,届时会重新实测更新。想下载这个版本,可以前往 F-Droid 下载页;想了解安装步骤,参见 F-Droid 安装教程

相关教程与资源

F-Droid 1.23.2 下载与校验值

官方客户端 APK,含完整 SHA-256 校验值、签名指纹与安装步骤。

2026-09 更新

F-Droid 安装完整教程

含华为、小米、OPPO、vivo、三星等品牌差异说明的详细安装步骤。

2026-08 更新

F-Droid 常见问题答疑

安全性、仓库配置、自动更新、权限管理等使用中的常见疑问解答。

2026-08 更新