Android APK 签名原理:到底在保护什么?

APK 签名不是“加密 APK”。

它主要解决两件事:

  1. APK 有没有被改过。

  2. 这个 APK 是否来自同一个签名身份。

APK 签名原理流程

1. 签名不是加密

签名不会隐藏 classes.dex、资源文件、Manifest,也不能阻止反编译。

它做的是完整性校验:APK 只要被改动,摘要就会变,验签就会失败。

能力

APK 签名是否负责

防篡改

证明应用身份

安全覆盖升级

防反编译

代码加密

防抓包

2. 签名原理

核心流程很简单:

  1. 对 APK 内容计算摘要,比如 SHA-256。

  2. 使用开发者私钥对摘要做数字签名。

  3. 把签名结果和证书写入 APK。

  4. 安装时,系统重新计算摘要。

  5. 系统用 APK 里的证书公钥验签。

  6. 验签通过,才允许安装或更新。

这里最关键的是:

内容

放在哪里

作用

私钥

keystore 中

用来签名,不能泄露

公钥证书

APK 中

用来验签,可以公开

摘要

签名信息中

判断内容是否变化

签名结果

APK 中

证明摘要确实由私钥签出

一句话:私钥签名,公钥验签。

3. 为什么不同签名不能覆盖安装?

Android 不只看包名,还会看签名证书。

比如原应用是:

项目

已安装应用

新 APK

packageName

com.example.app

com.example.app

签名证书

A

B

包名一样,但签名不一样,系统会拒绝覆盖安装。

原因很直接:如果系统只看包名,别人就可以做一个同包名 APK,覆盖你的正式应用,继承用户数据和权限。

所以签名证书也是应用身份的一部分。

4. APK 里的签名信息

不同签名方案,签名信息放的位置不一样。

APK 签名信息位置

v1 签名

v1 是老的 JAR 签名方案,签名文件在 META-INF/ 目录下。

常见文件:

文件

作用

MANIFEST.MF

记录 APK 内文件摘要

CERT.SF

记录摘要文件的摘要

CERT.RSA / CERT.DSA

保存签名和证书

v1 主要按 ZIP 条目校验,兼容老系统,但保护范围不如 v2/v3。

v2 签名

v2 从 Android 7.0 引入,是整包签名方案。

它把签名信息放在 APK Signing Block 中,位置在 ZIP Central Directory 之前。

v2 的重点:

  1. 对 APK 受保护部分做整体校验。

  2. 校验速度更快。

  3. APK 元数据被改,也更容易被发现。

v3 签名

v3 从 Android 9 引入,整体思路接近 v2。

它主要增加了密钥轮换能力,也就是可以记录旧签名 key 到新签名 key 的关系。

这解决的是“签名 key 想更换”的问题,而不是普通加固问题。

v4 签名

v4 从 Android 11 开始支持,主要服务流式安装、增量安装。

它不会把所有签名信息都塞进 APK,而是生成独立的 .idsig 文件。

注意:v4 不能单独替代 v2/v3。正常 APK 仍然需要 v2 或 v3 签名。

APK 签名方案演进

5. 开发中最容易踩的坑

debug 包和 release 包不能互相覆盖

通常是签名不同。

debug 包默认用 debug keystore,release 包用正式 keystore。包名相同也没用,系统会拦。

keystore 丢了很麻烦

如果不是通过 Google Play App Signing 托管签名 key,正式 keystore 丢失后,后续版本通常无法继续覆盖老版本。

所以正式 keystore 要备份,密码也要做权限管理。

多渠道包不能破坏签名

渠道信息如果写入 APK 后再改,可能导致签名失效。

正确做法是:先处理渠道信息,再签名;或者使用支持签名方案的渠道写入方式。

加固、重打包后要重新签名

APK 内容变了,原签名就失效。

加固平台、二次打包、多渠道处理之后,都要确认最终产物签名正确。

6. 怎么检查 APK 签名?

常用工具是 Android SDK 里的 apksigner

查看 APK 签名信息:

apksigner verify --verbose --print-certs app-release.apk

常见关注点:

字段

关注点

verified

是否验签通过

v1/v2/v3/v4

启用了哪些签名方案

certificate SHA-256 digest

证书指纹是否符合预期

7. 总结

APK 签名的本质:

用私钥给 APK 摘要签名,系统用公钥证书验签。

它保护的是:

  1. APK 完整性。

  2. 应用发布身份。

  3. 同包名覆盖升级安全。

它不保护:

  1. 代码不被看。

  2. 资源不被提取。

  3. 接口不被抓包。

  4. 业务逻辑不被破解。

所以不要把 APK 签名当成加固。

它是 Android 安装和升级链路里的身份机制。

参考资料

  1. Android Developers:Sign your app

  2. Android Open Source Project:App signing

  3. Android Open Source Project:APK Signature Scheme v2

  4. Android Open Source Project:APK Signature Scheme v3

  5. Android Open Source Project:APK Signature Scheme v4